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.
		
		
		
		
		
			
		
			
				
	
	
		
			231 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Dart
		
	
			
		
		
	
	
			231 lines
		
	
	
		
			10 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/appointemnet_filters.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/AppointmentFilter.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/date_range_selector/date_range_calender.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/date_range_selector/viewmodel/date_range_view_model.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';
 | |
| 
 | |
| import '../../widgets/common_bottom_sheet.dart'
 | |
|     show showCommonBottomSheetWithoutHeight;
 | |
| 
 | |
| 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);
 | |
|                   myAppointmentsViewModel.updateListWRTTab(index);
 | |
|                   context.read<DateRangeSelectorRangeViewModel>().flush();
 | |
|                 },
 | |
|               ).paddingSymmetrical(24.h, 0.h),
 | |
|               Consumer<MyAppointmentsViewModel>(builder: (context, myAppointmentsVM, child) {
 | |
|                 return getSelectedTabData(myAppointmentsVM.selectedTabIndex, myAppointmentsVM);
 | |
|               }),
 | |
|             ],
 | |
|           ),
 | |
|         ),
 | |
|       ),
 | |
|     );
 | |
|   }
 | |
| 
 | |
|   Widget getSelectedTabData(int index, MyAppointmentsViewModel myAppointmentsVM) {
 | |
|     return getAppointList(
 | |
|         myAppointmentsVM, myAppointmentsVM.filteredAppointmentList);
 | |
|   }
 | |
| 
 | |
|   Widget getAppointList(MyAppointmentsViewModel myAppointmentsVM,
 | |
|       List<PatientAppointmentHistoryResponseModel> filteredAppointmentList) {
 | |
|     return Column(
 | |
|       crossAxisAlignment: CrossAxisAlignment.start,
 | |
|       children: [
 | |
| 
 | |
|         Visibility(
 | |
|           visible: myAppointmentsVM.availableFilters.isNotEmpty,
 | |
|             child: getAppointmentFilters(myAppointmentsVM)),
 | |
|         ListView.separated(
 | |
|           padding: EdgeInsets.only(top: 24.h),
 | |
|           shrinkWrap: true,
 | |
|           physics: NeverScrollableScrollPhysics(),
 | |
|           itemCount: myAppointmentsVM.isMyAppointmentsLoading
 | |
|               ? 5
 | |
|               : filteredAppointmentList.isNotEmpty
 | |
|                   ? filteredAppointmentList.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)
 | |
|                 : filteredAppointmentList.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:
 | |
|                                     filteredAppointmentList[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),
 | |
|         ),
 | |
|         SizedBox(height: 24.h),
 | |
|       ],
 | |
|     );
 | |
|   }
 | |
| 
 | |
|   Widget getAppointmentFilters(MyAppointmentsViewModel myAppointmentsVM) {
 | |
|     return SizedBox(
 | |
|         height: 56.h,
 | |
|         child: Row(
 | |
|           children: [
 | |
|             Expanded(
 | |
|               child: ListView.separated(
 | |
|                   separatorBuilder: (_, index) => SizedBox(
 | |
|                         width: 8.h,
 | |
|                       ),
 | |
|                   scrollDirection: Axis.horizontal,
 | |
|                   itemCount: myAppointmentsVM.availableFilters.length,
 | |
|                   itemBuilder: (_, index) => AppointmentFilters(
 | |
|                         selectedFilter: myAppointmentsVM.selectedFilter,
 | |
|                         item: myAppointmentsVM.availableFilters[index],
 | |
|                         onClicked: () {
 | |
|                           if (myAppointmentsVM.availableFilters[index] ==
 | |
|                               AppointmentListingFilters.DATESELECTION) {
 | |
|                             showCommonBottomSheetWithoutHeight(
 | |
|                               title: "Set The Date Range".needTranslation,
 | |
|                               context,
 | |
|                               child: DateRangeSelector(
 | |
|                                 onRangeSelected: (start, end) {
 | |
|                                   // if (start != null) {
 | |
|                                   myAppointmentsVM.getSelectedDateRange(
 | |
|                                       start, end);
 | |
|                                   // }
 | |
|                                 },
 | |
|                               ),
 | |
|                               isFullScreen: false,
 | |
|                               isCloseButtonVisible: true,
 | |
|                               callBackFunc: () {},
 | |
|                             );
 | |
|                           } else {
 | |
|                             myAppointmentsVM.setSelectedFilter(
 | |
|                                 myAppointmentsVM.availableFilters[index]);
 | |
|                             myAppointmentsVM.filterTheListAsPerSelection();
 | |
|                           }
 | |
|                         },
 | |
|                       )),
 | |
|             ),
 | |
|           ],
 | |
|         )).paddingOnly(top: 24.h, left: 24.h, right: 24.h);
 | |
|   }
 | |
| }
 | |
| 
 |