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.
HMG_Patient_App_New/lib/presentation/home/landing_page.dart

461 lines
24 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:flutter_swiper_view/flutter_swiper_view.dart';
import 'package:get_it/get_it.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/cache_consts.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/extensions/int_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';
import 'package:hmg_patient_app_new/features/habib_wallet/habib_wallet_view_model.dart';
import 'package:hmg_patient_app_new/features/insurance/insurance_view_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/patient_appointment_history_response_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart';
import 'package:hmg_patient_app_new/features/prescriptions/prescriptions_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/appointments/my_appointments_page.dart';
import 'package:hmg_patient_app_new/presentation/appointments/widgets/appointment_card.dart';
import 'package:hmg_patient_app_new/presentation/authentication/quick_login.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/book_appointment_page.dart';
import 'package:hmg_patient_app_new/presentation/home/data/landing_page_data.dart';
import 'package:hmg_patient_app_new/presentation/home/widgets/habib_wallet_card.dart';
import 'package:hmg_patient_app_new/presentation/home/widgets/large_service_card.dart';
import 'package:hmg_patient_app_new/presentation/home/widgets/small_service_card.dart';
import 'package:hmg_patient_app_new/presentation/home/widgets/welcome_widget.dart';
import 'package:hmg_patient_app_new/presentation/lab/lab_results/lab_result_calender.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/services/cache_service.dart';
import 'package:hmg_patient_app_new/services/navigation_service.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/common_bottom_sheet.dart';
import 'package:hmg_patient_app_new/widgets/custom_tab_bar.dart' show CustomTabBar;
import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:hmg_patient_app_new/widgets/routes/spring_page_route_builder.dart';
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
import 'package:provider/provider.dart';
class LandingPage extends StatefulWidget {
const LandingPage({super.key});
@override
State<LandingPage> createState() => _LandingPageState();
}
class _LandingPageState extends State<LandingPage> {
late final AuthenticationViewModel authVM;
bool isDone = false;
late final HabibWalletViewModel habibWalletVM;
late AppState appState;
late MyAppointmentsViewModel myAppointmentsViewModel;
late PrescriptionsViewModel prescriptionsViewModel;
final CacheService cacheService = GetIt.instance<CacheService>();
late InsuranceViewModel insuranceViewModel;
final SwiperController _controller = SwiperController();
@override
void initState() {
authVM = context.read<AuthenticationViewModel>();
habibWalletVM = context.read<HabibWalletViewModel>();
authVM.savePushTokenToAppState();
if (mounted) {
authVM.checkLastLoginStatus(() {
showQuickLogin(context);
});
}
scheduleMicrotask(() {
if (appState.isAuthenticated) {
habibWalletVM.initHabibWalletProvider();
habibWalletVM.getPatientBalanceAmount();
myAppointmentsViewModel.initAppointmentsViewModel();
myAppointmentsViewModel.getPatientAppointments(true, false);
myAppointmentsViewModel.getPatientMyDoctors();
prescriptionsViewModel.initPrescriptionsViewModel();
insuranceViewModel.initInsuranceProvider();
}
});
super.initState();
}
@override
Widget build(BuildContext context) {
appState = getIt.get<AppState>();
NavigationService navigationService = getIt.get<NavigationService>();
myAppointmentsViewModel = Provider.of<MyAppointmentsViewModel>(context, listen: false);
prescriptionsViewModel = Provider.of<PrescriptionsViewModel>(context, listen: false);
insuranceViewModel = Provider.of<InsuranceViewModel>(context, listen: false);
return Scaffold(
backgroundColor: AppColors.bgScaffoldColor,
body: SingleChildScrollView(
padding: EdgeInsets.only(top: kToolbarHeight + 0.h, bottom: 24),
child: Column(
spacing: 16.h,
children: [
Row(
spacing: 8.h,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
appState.isAuthenticated
? WelcomeWidget(
onTap: () {
Navigator.of(context).push(springPageRoute(ProfileSettings()));
},
name: ('${appState.getAuthenticatedUser()!.firstName!} ${appState.getAuthenticatedUser()!.lastName!}'),
imageUrl: appState.getAuthenticatedUser()?.gender == 1 ? AppAssets.male_img : AppAssets.femaleImg,
).expanded
: CustomButton(
text: LocaleKeys.loginOrRegister.tr(context: context),
onPressed: () async {
await authVM.onLoginPressed();
},
backgroundColor: Color(0xffFEE9EA),
borderColor: Color(0xffFEE9EA),
textColor: Color(0xffED1C2B),
fontSize: 16,
fontWeight: FontWeight.w500,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 50,
),
Row(
mainAxisSize: MainAxisSize.min,
spacing: 12.h,
children: [
Utils.buildSvgWithAssets(icon: AppAssets.bell, height: 20, width: 20).onPress(() {
Navigator.of(context).push(
CustomPageRoute(
page: MedicalFilePage(),
// page: LoginScreen(),
),
);
}),
Utils.buildSvgWithAssets(icon: AppAssets.search_icon, height: 20, width: 20).onPress(() {
Navigator.of(context).push(
CustomPageRoute(
page: MedicalFilePage(),
// page: LoginScreen(),
),
);
}),
Utils.buildSvgWithAssets(icon: AppAssets.contact_icon, height: 20, width: 20).onPress(() {
Navigator.of(context).push(
CustomPageRoute(
page: MedicalFilePage(),
// page: LoginScreen(),
),
);
}),
],
)
],
).paddingSymmetrical(24.h, 0.h),
appState.isAuthenticated
? Column(
children: [
SizedBox(height: 12.h),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"Appointments & Visits".toText16(isBold: true),
Row(
children: [
LocaleKeys.viewAll.tr(context: context).toText12(color: AppColors.primaryRedColor),
SizedBox(width: 2.h),
Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h),
],
),
],
).paddingSymmetrical(24.h, 0.h).onPress(() {
Navigator.of(context).push(
CustomPageRoute(
page: MyAppointmentsPage(),
),
);
}),
SizedBox(height: 16.h),
Consumer<MyAppointmentsViewModel>(builder: (context, myAppointmentsVM, child) {
return myAppointmentsVM.isMyAppointmentsLoading
? Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true),
child: AppointmentCard(
patientAppointmentHistoryResponseModel: PatientAppointmentHistoryResponseModel(),
myAppointmentsViewModel: myAppointmentsViewModel,
isLoading: true,
isFromHomePage: true,
),
).paddingSymmetrical(24.h, 0.h)
: myAppointmentsVM.patientAppointmentsHistoryList.isNotEmpty
? myAppointmentsVM.patientAppointmentsHistoryList.length == 1
? Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true),
child: AppointmentCard(
patientAppointmentHistoryResponseModel: myAppointmentsVM.patientAppointmentsHistoryList.first,
myAppointmentsViewModel: myAppointmentsViewModel,
isLoading: false,
isFromHomePage: true,
),
).paddingSymmetrical(24.h, 0.h)
: Swiper(
itemCount: myAppointmentsVM.isMyAppointmentsLoading
? 3
: myAppointmentsVM.patientAppointmentsHistoryList.length < 3
? myAppointmentsVM.patientAppointmentsHistoryList.length
: 3,
layout: SwiperLayout.STACK,
loop: true,
itemWidth: MediaQuery.of(context).size.width - 48.h,
indicatorLayout: PageIndicatorLayout.COLOR,
axisDirection: AxisDirection.right,
controller: _controller,
itemHeight: 210 + 25,
pagination: const SwiperPagination(
alignment: Alignment.bottomCenter,
margin: EdgeInsets.only(top: 210 + 8 + 24),
builder: DotSwiperPaginationBuilder(color: Color(0xffD9D9D9), activeColor: AppColors.blackBgColor),
),
itemBuilder: (BuildContext context, int index) {
return Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true),
child: AppointmentCard(
patientAppointmentHistoryResponseModel: myAppointmentsVM.patientAppointmentsHistoryList[index],
myAppointmentsViewModel: myAppointmentsViewModel,
isLoading: false,
isFromHomePage: true,
),
);
},
)
: Container(
width: double.infinity,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24, hasShadow: true),
child: Padding(
padding: EdgeInsets.all(12.h),
child: Column(
children: [
Utils.buildSvgWithAssets(icon: AppAssets.home_calendar_icon, width: 32.h, height: 32.h),
SizedBox(height: 12.h),
"You do not have any upcoming appointment. Please book an appointment".needTranslation.toText12(isCenter: true),
SizedBox(height: 12.h),
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(24.h, 0.h);
}),
SizedBox(height: 12.h),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"Quick Links".toText16(isBold: true),
Row(
children: [
"View medical file".toText12(color: AppColors.primaryRedColor),
SizedBox(width: 2.h),
Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h),
],
),
],
).paddingSymmetrical(24.h, 0.h).onPress(() {
Navigator.of(context).push(
CustomPageRoute(
page: MedicalFilePage(),
),
);
}),
SizedBox(height: 16.h),
Container(
height: 120.h,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 24,
),
child: Column(
children: [
Expanded(
child: ListView.separated(
scrollDirection: Axis.horizontal,
itemCount: LandingPageData.getLoggedInServiceCardsList.length,
shrinkWrap: true,
padding: EdgeInsets.only(left: 16.h, right: 16.h),
itemBuilder: (context, index) {
return AnimationConfiguration.staggeredList(
position: index,
duration: const Duration(milliseconds: 1000),
child: SlideAnimation(
horizontalOffset: 100.0,
child: FadeInAnimation(
child: SmallServiceCard(
icon: LandingPageData.getLoggedInServiceCardsList[index].icon,
title: LandingPageData.getLoggedInServiceCardsList[index].title,
subtitle: LandingPageData.getLoggedInServiceCardsList[index].subtitle,
iconColor: LandingPageData.getLoggedInServiceCardsList[index].iconColor,
textColor: LandingPageData.getLoggedInServiceCardsList[index].textColor,
backgroundColor: LandingPageData.getLoggedInServiceCardsList[index].backgroundColor,
isBold: LandingPageData.getLoggedInServiceCardsList[index].isBold,
serviceName: LandingPageData.getLoggedInServiceCardsList[index].serviceName,
),
),
),
);
},
separatorBuilder: (BuildContext cxt, int index) => 0.width,
),
),
],
),
).paddingSymmetrical(24.h, 0.h),
],
)
: Container(
height: 127.h,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 24,
),
child: Column(
children: [
Expanded(
child: ListView.separated(
scrollDirection: Axis.horizontal,
itemCount: LandingPageData.getNotLoggedInServiceCardsList.length,
shrinkWrap: true,
padding: EdgeInsets.only(left: 16.h, right: 16.h),
itemBuilder: (context, index) {
return AnimationConfiguration.staggeredList(
position: index,
duration: const Duration(milliseconds: 1000),
child: SlideAnimation(
horizontalOffset: 100.0,
child: FadeInAnimation(
child: SmallServiceCard(
icon: LandingPageData.getNotLoggedInServiceCardsList[index].icon,
title: LandingPageData.getNotLoggedInServiceCardsList[index].title,
subtitle: LandingPageData.getNotLoggedInServiceCardsList[index].subtitle,
iconColor: LandingPageData.getNotLoggedInServiceCardsList[index].iconColor,
textColor: LandingPageData.getNotLoggedInServiceCardsList[index].textColor,
backgroundColor: LandingPageData.getNotLoggedInServiceCardsList[index].backgroundColor,
isBold: LandingPageData.getNotLoggedInServiceCardsList[index].isBold,
),
),
),
);
},
separatorBuilder: (BuildContext cxt, int index) => 0.width,
),
),
],
),
).paddingSymmetrical(24.h, 0.h),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"Services".toText16(isBold: true),
Row(
children: [
"View all services".toText12(color: AppColors.primaryRedColor),
SizedBox(width: 2.h),
Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h),
],
),
],
).paddingSymmetrical(24.h, 0.h),
SizedBox(
height: 325.h,
child: Column(
children: [
Expanded(
child: ListView.separated(
scrollDirection: Axis.horizontal,
itemCount: LandingPageData.getServiceCardsList.length,
shrinkWrap: true,
padding: EdgeInsets.only(left: 24.h, right: 24.h),
itemBuilder: (context, index) {
return AnimationConfiguration.staggeredList(
position: index,
duration: const Duration(milliseconds: 1000),
child: SlideAnimation(
horizontalOffset: 100.0,
child: FadeInAnimation(
child: LargeServiceCard(
image: LandingPageData.getServiceCardsList[index].icon,
title: LandingPageData.getServiceCardsList[index].title,
subtitle: LandingPageData.getServiceCardsList[index].subtitle,
icon: LandingPageData.getServiceCardsList[index].largeCardIcon,
),
),
),
);
},
separatorBuilder: (BuildContext cxt, int index) => 8.width,
),
),
],
),
),
appState.isAuthenticated ? HabibWalletCard() : SizedBox(),
],
),
),
);
}
void showQuickLogin(BuildContext context) {
showCommonBottomSheetWithoutHeight(
context,
title: "",
isCloseButtonVisible: false,
child: StatefulBuilder(builder: (context, setState) {
return QuickLogin(
isDone: isDone,
onPressed: () {
// sharedPref.setBool(HAS_ENABLED_QUICK_LOGIN, true);
authVM.loginWithFingerPrintFace(() {
isDone = true;
cacheService.saveBool(key: CacheConst.quickLoginEnabled, value: true);
setState(() {});
});
},
);
}),
// height: isDone == false ? ResponsiveExtension.screenHeight * 0.5 : ResponsiveExtension.screenHeight * 0.3,
isFullScreen: false,
callBackFunc: () {
isDone = true;
setState(() {});
},
);
}
}