empty state implementation contd.

pull/62/head
haroon amjad 1 month ago
parent 62e82a7a31
commit 6b28b57307

@ -301,16 +301,17 @@ class Utils {
return false; return false;
} }
static Widget getNoDataWidget(BuildContext context, {String? noDataText}) { static Widget getNoDataWidget(BuildContext context, {double width = 124, double height = 124, String? noDataText, Widget callToActionButton = const SizedBox.shrink(), bool isSmallWidget = false}) {
return Column( return Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
SizedBox(height: 48.h), SizedBox(height: isSmallWidget ? 0.h : 48.h),
Lottie.asset(AppAnimations.noData, repeat: false, reverse: false, frameRate: FrameRate(60), width: 150.h, height: 150.h, fit: BoxFit.fill), Lottie.asset(AppAnimations.noData, repeat: false, reverse: false, frameRate: FrameRate(60), width: width.h, height: height.h, fit: BoxFit.fill),
SizedBox(height: 12.h), SizedBox(height: 16.h),
(noDataText ?? LocaleKeys.noDataAvailable.tr()).toText16(weight: FontWeight.w500, color: AppColors.greyTextColor), (noDataText ?? LocaleKeys.noDataAvailable.tr()).toText16(weight: FontWeight.w500, color: AppColors.greyTextColor, isCenter: true).paddingSymmetrical(64.h, 0.h),
SizedBox(height: 12.h), SizedBox(height: 16.h),
callToActionButton
], ],
).center; ).center;
} }

@ -71,6 +71,7 @@ class PrescriptionsViewModel extends ChangeNotifier {
// (failure) async => await errorHandlerService.handleError(failure: failure), // (failure) async => await errorHandlerService.handleError(failure: failure),
(failure) async { (failure) async {
isPrescriptionsOrdersLoading = false; isPrescriptionsOrdersLoading = false;
notifyListeners();
}, },
(apiResponse) { (apiResponse) {
if (apiResponse.messageStatus == 2) { if (apiResponse.messageStatus == 2) {

@ -1,17 +1,23 @@
import 'dart:async'; import 'dart:async';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_staggered_animations/flutter_staggered_animations.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/size_utils.dart';
import 'package:hmg_patient_app_new/core/utils/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/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_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/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/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/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/widgets/appbar/collapsing_list_view.dart';
import 'package:hmg_patient_app_new/theme/colors.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/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:hmg_patient_app_new/widgets/shimmer/movies_shimmer_widget.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -116,7 +122,30 @@ class _MyAppointmentsPageState extends State<MyAppointmentsPage> {
), ),
), ),
) )
: Utils.getNoDataWidget(context, noDataText: "You don't have any appointments yet.".needTranslation); : 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), separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h),
), ),
@ -159,7 +188,30 @@ class _MyAppointmentsPageState extends State<MyAppointmentsPage> {
), ),
), ),
) )
: Utils.getNoDataWidget(context, noDataText: "You don't have any appointments yet.".needTranslation); : 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), separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h),
), ),
@ -202,7 +254,30 @@ class _MyAppointmentsPageState extends State<MyAppointmentsPage> {
), ),
), ),
) )
: Utils.getNoDataWidget(context, noDataText: "You don't have any appointments yet.".needTranslation); : 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), separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h),
), ),
@ -213,3 +288,4 @@ class _MyAppointmentsPageState extends State<MyAppointmentsPage> {
} }
} }
} }

@ -58,7 +58,7 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
backgroundColor: AppColors.bgScaffoldColor, backgroundColor: AppColors.bgScaffoldColor,
body: CollapsingListView( body: CollapsingListView(
title: LocaleKeys.bookAppo.tr(context: context), title: LocaleKeys.bookAppo.tr(context: context),
isLeading: false, isLeading: Navigator.of(context).canPop(),
child: SingleChildScrollView( child: SingleChildScrollView(
child: Consumer<BookAppointmentsViewModel>(builder: (context, bookAppointmentsVM, child) { child: Consumer<BookAppointmentsViewModel>(builder: (context, bookAppointmentsVM, child) {
return Column( return Column(

@ -179,7 +179,7 @@ class _LandingPageState extends State<LandingPage> {
), ),
); );
}), }),
SizedBox(height: 12.h), SizedBox(height: 16.h),
Consumer<MyAppointmentsViewModel>(builder: (context, myAppointmentsVM, child) { Consumer<MyAppointmentsViewModel>(builder: (context, myAppointmentsVM, child) {
return myAppointmentsVM.isMyAppointmentsLoading return myAppointmentsVM.isMyAppointmentsLoading
? Container( ? Container(
@ -288,15 +288,13 @@ class _LandingPageState extends State<LandingPage> {
), ),
); );
}), }),
SizedBox(height: 12.h), SizedBox(height: 16.h),
Container( Container(
height: 127.h, height: 120.h,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration( decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor, color: AppColors.whiteColor,
borderRadius: 24, borderRadius: 24,
), ),
child: Padding(
padding: EdgeInsets.all(16.h),
child: Column( child: Column(
children: [ children: [
Expanded( Expanded(
@ -304,7 +302,7 @@ class _LandingPageState extends State<LandingPage> {
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
itemCount: LandingPageData.getLoggedInServiceCardsList.length, itemCount: LandingPageData.getLoggedInServiceCardsList.length,
shrinkWrap: true, shrinkWrap: true,
padding: const EdgeInsets.only(left: 0, right: 8), padding: EdgeInsets.only(left: 16.h, right: 16.h),
itemBuilder: (context, index) { itemBuilder: (context, index) {
return AnimationConfiguration.staggeredList( return AnimationConfiguration.staggeredList(
position: index, position: index,
@ -331,7 +329,6 @@ class _LandingPageState extends State<LandingPage> {
), ),
], ],
), ),
),
).paddingSymmetrical(24.h, 0.h), ).paddingSymmetrical(24.h, 0.h),
], ],
) )
@ -341,8 +338,6 @@ class _LandingPageState extends State<LandingPage> {
color: AppColors.whiteColor, color: AppColors.whiteColor,
borderRadius: 24, borderRadius: 24,
), ),
child: Padding(
padding: EdgeInsets.all(16.h),
child: Column( child: Column(
children: [ children: [
Expanded( Expanded(
@ -350,7 +345,7 @@ class _LandingPageState extends State<LandingPage> {
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
itemCount: LandingPageData.getNotLoggedInServiceCardsList.length, itemCount: LandingPageData.getNotLoggedInServiceCardsList.length,
shrinkWrap: true, shrinkWrap: true,
padding: const EdgeInsets.only(left: 0, right: 8), padding: EdgeInsets.only(left: 16.h, right: 16.h),
itemBuilder: (context, index) { itemBuilder: (context, index) {
return AnimationConfiguration.staggeredList( return AnimationConfiguration.staggeredList(
position: index, position: index,
@ -376,7 +371,6 @@ class _LandingPageState extends State<LandingPage> {
), ),
], ],
), ),
),
).paddingSymmetrical(24.h, 0.h), ).paddingSymmetrical(24.h, 0.h),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,

@ -39,7 +39,7 @@ class SmallServiceCard extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Padding( return Padding(
padding: EdgeInsets.symmetric(horizontal: 3.h), padding: EdgeInsets.symmetric(horizontal: 0.h, vertical: 12.h),
child: Container( child: Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration( decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: backgroundColor, color: backgroundColor,

@ -275,7 +275,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
}), }),
Consumer<MyAppointmentsViewModel>(builder: (context, myAppointmentsVM, child) { Consumer<MyAppointmentsViewModel>(builder: (context, myAppointmentsVM, child) {
return SizedBox( return SizedBox(
height: 200.h, height: myAppointmentsVM.patientAppointmentsHistoryList.isNotEmpty ? 200.h : 175.h,
child: ListView.separated( child: ListView.separated(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
padding: EdgeInsets.only(top: 16.h, left: 24.h, right: 24.h, bottom: 0.h), padding: EdgeInsets.only(top: 16.h, left: 24.h, right: 24.h, bottom: 0.h),
@ -500,7 +500,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
), ),
), ),
).paddingSymmetrical(24.h, 0.h) ).paddingSymmetrical(24.h, 0.h)
: SizedBox.shrink(); : Utils.getNoDataWidget(context, noDataText: "You don't have any prescriptions yet.".needTranslation, isSmallWidget: true, width: 62, height: 62).paddingSymmetrical(24.h, 0.h);
}), }),
SizedBox(height: 24.h), SizedBox(height: 24.h),
//My Doctor Section //My Doctor Section
@ -531,7 +531,11 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
height: 120.h, height: 120.h,
child: ListView.separated( child: ListView.separated(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
itemCount: myAppointmentsVM.isPatientMyDoctorsLoading ? 5 : myAppointmentsVM.patientMyDoctorsList.length, itemCount: myAppointmentsVM.isPatientMyDoctorsLoading
? 5
: myAppointmentsVM.patientMyDoctorsList.isNotEmpty
? myAppointmentsVM.patientMyDoctorsList.length
: 1,
shrinkWrap: true, shrinkWrap: true,
padding: EdgeInsets.only(left: 24.h, right: 24.h), padding: EdgeInsets.only(left: 24.h, right: 24.h),
itemBuilder: (context, index) { itemBuilder: (context, index) {
@ -554,7 +558,8 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
], ],
), ),
) )
: AnimationConfiguration.staggeredList( : myAppointmentsVM.patientMyDoctorsList.isNotEmpty
? AnimationConfiguration.staggeredList(
position: index, position: index,
duration: const Duration(milliseconds: 1000), duration: const Duration(milliseconds: 1000),
child: SlideAnimation( child: SlideAnimation(
@ -583,7 +588,9 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
), ),
), ),
), ),
); )
: Utils.getNoDataWidget(context, noDataText: "You don't have any completed visits yet.".needTranslation, isSmallWidget: true, width: 62, height: 62)
.paddingSymmetrical(24.h, 0.h);
}, },
separatorBuilder: (BuildContext cxt, int index) => SizedBox(width: 8.h), separatorBuilder: (BuildContext cxt, int index) => SizedBox(width: 8.h),
), ),

@ -4,6 +4,8 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.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/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/medical_file/medical_file_view_model.dart'; import 'package:hmg_patient_app_new/features/medical_file/medical_file_view_model.dart';
import 'package:hmg_patient_app_new/features/medical_file/models/patient_sickleave_response_model.dart'; import 'package:hmg_patient_app_new/features/medical_file/models/patient_sickleave_response_model.dart';
@ -50,7 +52,11 @@ class _PatientSickleavesListPageState extends State<PatientSickleavesListPage> {
children: [ children: [
ListView.separated( ListView.separated(
scrollDirection: Axis.vertical, scrollDirection: Axis.vertical,
itemCount: medicalFileVM.isPatientSickLeaveListLoading ? 3 : medicalFileVM.patientSickLeaveList.length, itemCount: medicalFileVM.isPatientSickLeaveListLoading
? 3
: medicalFileVM.patientSickLeaveList.isNotEmpty
? medicalFileVM.patientSickLeaveList.length
: 1,
shrinkWrap: true, shrinkWrap: true,
physics: NeverScrollableScrollPhysics(), physics: NeverScrollableScrollPhysics(),
itemBuilder: (context, index) { itemBuilder: (context, index) {
@ -73,7 +79,7 @@ class _PatientSickleavesListPageState extends State<PatientSickleavesListPage> {
), ),
), ),
) )
: SizedBox.shrink(); : Utils.getNoDataWidget(context, noDataText: "You don't have any sick leaves yet.".needTranslation);
}, },
separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 8.h), separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 8.h),
), ),

@ -43,7 +43,7 @@ class PatientSickLeaveCard extends StatelessWidget {
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
"${LocaleKeys.sick.tr(context: context)} ${LocaleKeys.sickSubtitle.tr(context: context)}".toText16(isBold: true), "${LocaleKeys.sick.tr(context: context)} ${LocaleKeys.sickSubtitle.tr(context: context)}".toText16(isBold: true).toShimmer2(isShow: isLoading),
AppCustomChipWidget( AppCustomChipWidget(
labelText: isLoading ? "" : getStatusText(context), labelText: isLoading ? "" : getStatusText(context),
backgroundColor: getStatusColor().withOpacity(0.15), backgroundColor: getStatusColor().withOpacity(0.15),

@ -13,6 +13,7 @@ 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/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/prescriptions/prescriptions_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/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/lab/lab_result_item_view.dart';
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
import 'package:hmg_patient_app_new/presentation/prescriptions/prescription_detail_page.dart'; import 'package:hmg_patient_app_new/presentation/prescriptions/prescription_detail_page.dart';
import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/theme/colors.dart';
@ -93,15 +94,25 @@ class _PrescriptionsListPageState extends State<PrescriptionsListPage> {
SizedBox(height: 20.h), SizedBox(height: 20.h),
// Expandable list // Expandable list
ListView.builder( ListView.builder(
itemCount: model.isPrescriptionsOrdersLoading ? 4 : model.patientPrescriptionOrdersViewList.length, itemCount: model.isPrescriptionsOrdersLoading
? 4
: model.patientPrescriptionOrders.isNotEmpty
? model.patientPrescriptionOrdersViewList.length
: 1,
physics: NeverScrollableScrollPhysics(), physics: NeverScrollableScrollPhysics(),
shrinkWrap: true, shrinkWrap: true,
padding: const EdgeInsets.only(left: 0, right: 8), padding: const EdgeInsets.only(left: 0, right: 8),
itemBuilder: (context, index) { itemBuilder: (context, index) {
final isExpanded = expandedIndex == index; final isExpanded = expandedIndex == index;
return model.isPrescriptionsOrdersLoading return model.isPrescriptionsOrdersLoading
? const MoviesShimmerWidget() ? LabResultItemView(
: AnimationConfiguration.staggeredList( onTap: () {},
labOrder: null,
index: index,
isLoading: true,
)
: model.patientPrescriptionOrders.isNotEmpty
? AnimationConfiguration.staggeredList(
position: index, position: index,
duration: const Duration(milliseconds: 500), duration: const Duration(milliseconds: 500),
child: SlideAnimation( child: SlideAnimation(
@ -290,7 +301,8 @@ class _PrescriptionsListPageState extends State<PrescriptionsListPage> {
), ),
), ),
), ),
); )
: Utils.getNoDataWidget(context, noDataText: "You don't have any prescriptions yet.".needTranslation);
}, },
).paddingSymmetrical(24.h, 0.h), ).paddingSymmetrical(24.h, 0.h),
], ],

@ -11,6 +11,7 @@ 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/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/features/lab/lab_view_model.dart'; import 'package:hmg_patient_app_new/features/lab/lab_view_model.dart';
import 'package:hmg_patient_app_new/presentation/lab/lab_result_item_view.dart';
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
import 'package:hmg_patient_app_new/presentation/radiology/radiology_result_page.dart'; import 'package:hmg_patient_app_new/presentation/radiology/radiology_result_page.dart';
import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/theme/colors.dart';
@ -68,7 +69,14 @@ class _RadiologyOrdersPageState extends State<RadiologyOrdersPage> {
: 1, : 1,
itemBuilder: (context, index) { itemBuilder: (context, index) {
final isExpanded = expandedIndex == index; final isExpanded = expandedIndex == index;
return model.patientRadiologyOrders.isNotEmpty return model.isRadiologyOrdersLoading
? LabResultItemView(
onTap: () {},
labOrder: null,
index: index,
isLoading: true,
)
: model.patientRadiologyOrders.isNotEmpty
? AnimationConfiguration.staggeredList( ? AnimationConfiguration.staggeredList(
position: index, position: index,
duration: const Duration(milliseconds: 500), duration: const Duration(milliseconds: 500),

Loading…
Cancel
Save