medical file implementation contd.

pull/28/head
Haroon Amjad 2 months ago
parent d87562caf5
commit 5620cc4442

@ -0,0 +1,5 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.50024 0.84375C7.08603 0.84375 6.75024 1.17954 6.75024 1.59375C6.75024 2.00796 7.08603 2.34375 7.50024 2.34375H8.25024V2.56924C4.56399 2.94479 1.68774 6.05838 1.68774 9.84375C1.68774 11.4006 2.17429 12.8439 3.00361 14.0297L1.71991 15.3134C1.42702 15.6063 1.42702 16.0812 1.71991 16.3741C2.01281 16.667 2.48768 16.667 2.78057 16.3741L3.98717 15.1675C5.2962 16.4006 7.05997 17.1562 9.00024 17.1562C10.9405 17.1562 12.7043 16.4006 14.0133 15.1675L15.2199 16.3741C15.5128 16.667 15.9877 16.667 16.2806 16.3741C16.5735 16.0812 16.5735 15.6063 16.2806 15.3134L14.9969 14.0297C15.8262 12.8439 16.3127 11.4006 16.3127 9.84375C16.3127 6.05838 13.4365 2.94479 9.75024 2.56924V2.34375L10.5002 2.34375C10.9145 2.34375 11.2502 2.00796 11.2502 1.59375C11.2502 1.17954 10.9145 0.84375 10.5002 0.84375L7.50024 0.84375ZM9.75024 7.21875C9.75024 6.80454 9.41446 6.46875 9.00024 6.46875C8.58603 6.46875 8.25024 6.80454 8.25024 7.21875L8.25024 10.2187C8.25024 10.4177 8.32926 10.6084 8.46991 10.7491L9.96991 12.2491C10.2628 12.542 10.7377 12.542 11.0306 12.2491C11.3235 11.9562 11.3235 11.4813 11.0306 11.1884L9.75024 9.90809V7.21875Z" fill="#ED1C2B"/>
<path d="M3.63891 1.87677C3.31491 1.71477 2.90547 1.53727 2.44764 1.6109C1.98924 1.68461 1.65565 1.98199 1.39707 2.24057C1.13848 2.49916 0.841106 2.83274 0.767389 3.29115C0.693766 3.74898 0.871267 4.15842 1.03327 4.48242L1.25658 4.92904C1.44182 5.29952 1.89232 5.44969 2.26281 5.26445C2.63329 5.07921 2.78346 4.6287 2.59822 4.25822L2.37491 3.8116C2.30362 3.66903 2.27107 3.58504 2.25679 3.53387L2.25589 3.53059L2.25771 3.52787C2.28727 3.4839 2.34472 3.41424 2.45773 3.30123C2.57073 3.18823 2.64039 3.13077 2.68436 3.10121L2.68708 3.0994L2.69037 3.1003C2.74153 3.11457 2.82552 3.14713 2.96809 3.21841L3.41471 3.44172C3.7852 3.62697 4.2357 3.4768 4.42094 3.10631C4.60619 2.73583 4.45602 2.28532 4.08553 2.10008L3.63891 1.87677Z" fill="#ED1C2B"/>
<path d="M15.0322 3.21841C15.1747 3.14713 15.2587 3.11457 15.3099 3.1003L15.3132 3.0994L15.3159 3.10121C15.3599 3.13077 15.4295 3.18823 15.5425 3.30123C15.6555 3.41424 15.713 3.4839 15.7425 3.52787L15.7444 3.53059L15.7435 3.53387C15.7292 3.58504 15.6966 3.66903 15.6253 3.8116L15.402 4.25822C15.2168 4.6287 15.367 5.07921 15.7374 5.26445C16.1079 5.44969 16.5584 5.29952 16.7437 4.92904L16.967 4.48242C17.129 4.15842 17.3065 3.74898 17.2329 3.29115C17.1591 2.83275 16.8618 2.49916 16.6032 2.24057C16.3446 1.98199 16.011 1.68461 15.5526 1.6109C15.0948 1.53727 14.6853 1.71477 14.3613 1.87677L13.9147 2.10008C13.5442 2.28532 13.3941 2.73583 13.5793 3.10631C13.7645 3.4768 14.215 3.62697 14.5855 3.44172L15.0322 3.21841Z" fill="#ED1C2B"/>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

@ -99,6 +99,7 @@ class AppAssets {
static const String notes_icon = '$svgBasePath/notes_icon.svg';
static const String forward_chevron_icon = '$svgBasePath/forward_chevron_icon.svg';
static const String logout = '$svgBasePath/logout.svg';
static const String alarm_clock_icon = '$svgBasePath/alarm_clock_icon.svg';
//bottom navigation//
static const String homeBottom = '$svgBasePath/home_bottom.svg';

@ -32,6 +32,8 @@ abstract class MyAppointmentsRepo {
Future<Either<Failure, GenericApiModel<dynamic>>> sendCheckInNfcRequest(
{required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel, required String scannedCode, required int checkInType});
Future<Either<Failure, GenericApiModel<List<PatientAppointmentHistoryResponseModel>>>> getPatientAppointmentsForTimeLine();
}
class MyAppointmentsRepoImp implements MyAppointmentsRepo {
@ -395,4 +397,51 @@ class MyAppointmentsRepoImp implements MyAppointmentsRepo {
return Left(UnknownFailure(e.toString()));
}
}
@override
Future<Either<Failure, GenericApiModel<List<PatientAppointmentHistoryResponseModel>>>> getPatientAppointmentsForTimeLine() async {
Map<String, dynamic> mapDevice = {
"isDentalAllowedBackend": false,
"PatientTypeID": 1,
"IsComingFromCOC": false,
"PatientType": 1,
"IsForTimeLine": true,
};
try {
GenericApiModel<List<PatientAppointmentHistoryResponseModel>>? apiResponse;
Failure? failure;
await apiClient.post(
GET_PATIENT_APPOINTMENT_HISTORY,
body: mapDevice,
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
},
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
final list = response['AppoimentAllHistoryResultList'];
// if (list == null || list.isEmpty) {
// throw Exception("Appointments list is empty");
// }
final appointmentsList = list.map((item) => PatientAppointmentHistoryResponseModel.fromJson(item as Map<String, dynamic>)).toList().cast<PatientAppointmentHistoryResponseModel>();
apiResponse = GenericApiModel<List<PatientAppointmentHistoryResponseModel>>(
messageStatus: messageStatus,
statusCode: statusCode,
errorMessage: null,
data: appointmentsList,
);
} catch (e) {
failure = DataParsingFailure(e.toString());
}
},
);
if (failure != null) return Left(failure!);
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
return Right(apiResponse!);
} catch (e) {
return Left(UnknownFailure(e.toString()));
}
}
}

@ -12,12 +12,15 @@ class MyAppointmentsViewModel extends ChangeNotifier {
bool isMyAppointmentsLoading = false;
bool isAppointmentPatientShareLoading = false;
bool isTimeLineAppointmentsLoading = false;
List<PatientAppointmentHistoryResponseModel> patientAppointmentsHistoryList = [];
List<PatientAppointmentHistoryResponseModel> patientUpcomingAppointmentsHistoryList = [];
List<PatientAppointmentHistoryResponseModel> patientArrivedAppointmentsHistoryList = [];
List<PatientAppointmentHistoryResponseModel> patientTimelineAppointmentsList = [];
PatientAppointmentShareResponseModel? patientAppointmentShareResponseModel;
MyAppointmentsViewModel({required this.myAppointmentsRepo, required this.errorHandlerService});
@ -31,8 +34,10 @@ class MyAppointmentsViewModel extends ChangeNotifier {
patientAppointmentsHistoryList.clear();
patientUpcomingAppointmentsHistoryList.clear();
patientArrivedAppointmentsHistoryList.clear();
patientTimelineAppointmentsList.clear();
isMyAppointmentsLoading = true;
isAppointmentPatientShareLoading = true;
isTimeLineAppointmentsLoading = true;
notifyListeners();
}
@ -46,6 +51,11 @@ class MyAppointmentsViewModel extends ChangeNotifier {
notifyListeners();
}
setIsPatientTimeLineAppointmentLoading(bool val) {
isTimeLineAppointmentsLoading = val;
notifyListeners();
}
setAppointmentReminder(bool value, PatientAppointmentHistoryResponseModel item) {
int index = patientAppointmentsHistoryList.indexOf(item);
if (index != -1) {

@ -57,8 +57,8 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
@override
Widget build(BuildContext context) {
myAppointmentsViewModel = Provider.of<MyAppointmentsViewModel>(context);
prescriptionsViewModel = Provider.of<PrescriptionsViewModel>(context);
myAppointmentsViewModel = Provider.of<MyAppointmentsViewModel>(context, listen: false);
prescriptionsViewModel = Provider.of<PrescriptionsViewModel>(context, listen: false);
return Scaffold(
backgroundColor: AppColors.bgScaffoldColor,
body: Column(

@ -35,7 +35,7 @@ class _MyAppointmentsPageState extends State<MyAppointmentsPage> {
@override
Widget build(BuildContext context) {
myAppointmentsViewModel = Provider.of<MyAppointmentsViewModel>(context);
myAppointmentsViewModel = Provider.of<MyAppointmentsViewModel>(context, listen: false);
return Scaffold(
backgroundColor: AppColors.bgScaffoldColor,
body: CollapsingListView(

@ -13,6 +13,8 @@ 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/models/habib_wallet_view_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/authentication/quick_login.dart';
import 'package:hmg_patient_app_new/presentation/home/data/landing_page_data.dart';
@ -43,6 +45,8 @@ class _LandingPageState extends State<LandingPage> {
late final HabibWalletViewModel habibWalletVM;
late AppState appState;
late MyAppointmentsViewModel myAppointmentsViewModel;
late PrescriptionsViewModel prescriptionsViewModel;
@override
void initState() {
@ -51,13 +55,16 @@ class _LandingPageState extends State<LandingPage> {
authVM.savePushTokenToAppState();
if (mounted) {
authVM.checkLastLoginStatus(() {
showQuickLogin(context);
showQuickLogin(context);
});
}
scheduleMicrotask(() {
if (appState.isAuthenticated) {
habibWalletVM.initHabibWalletProvider();
habibWalletVM.getPatientBalanceAmount();
myAppointmentsViewModel.initAppointmentsViewModel();
myAppointmentsViewModel.getPatientAppointments(true, false);
prescriptionsViewModel.initPrescriptionsViewModel();
}
});
super.initState();
@ -67,7 +74,8 @@ class _LandingPageState extends State<LandingPage> {
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);
return Scaffold(
backgroundColor: AppColors.bgScaffoldColor,
body: SingleChildScrollView(
@ -338,29 +346,22 @@ class _LandingPageState extends State<LandingPage> {
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;
setState(() {
child: StatefulBuilder(builder: (context, setState) {
return QuickLogin(
isDone: isDone,
onPressed: () {
// sharedPref.setBool(HAS_ENABLED_QUICK_LOGIN, true);
authVM.loginWithFingerPrintFace(() {
isDone = true;
setState(() {});
});
});
},
);
},
);
}),
// height: isDone == false ? ResponsiveExtension.screenHeight * 0.5 : ResponsiveExtension.screenHeight * 0.3,
// height: isDone == false ? ResponsiveExtension.screenHeight * 0.5 : ResponsiveExtension.screenHeight * 0.3,
isFullScreen: false,
callBackFunc: () {
isDone = true;

@ -2,18 +2,25 @@ 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/app_state.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:hmg_patient_app_new/core/utils/date_util.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/insurance/insurance_view_model.dart';
import 'package:hmg_patient_app_new/features/medical_file/medical_file_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/insurance/widgets/patient_insurance_card.dart';
import 'package:hmg_patient_app_new/presentation/lab/collapsing_list_view.dart';
import 'package:hmg_patient_app_new/presentation/medical_file/widgets/lab_rad_card.dart';
import 'package:hmg_patient_app_new/presentation/medical_file/widgets/medical_file_card.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
@ -23,6 +30,8 @@ import 'package:hmg_patient_app_new/widgets/shimmer/movies_shimmer_widget.dart';
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
import 'package:provider/provider.dart';
import 'widgets/medical_file_appointment_card.dart';
class MedicalFilePage extends StatefulWidget {
MedicalFilePage({super.key});
@ -33,6 +42,7 @@ class MedicalFilePage extends StatefulWidget {
class _MedicalFilePageState extends State<MedicalFilePage> {
late InsuranceViewModel insuranceViewModel;
late AppState appState;
late MyAppointmentsViewModel myAppointmentsViewModel;
int currentIndex = 0;
@ -46,174 +56,174 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
@override
Widget build(BuildContext context) {
insuranceViewModel = Provider.of<InsuranceViewModel>(context);
insuranceViewModel = Provider.of<InsuranceViewModel>(context, listen: false);
myAppointmentsViewModel = Provider.of<MyAppointmentsViewModel>(context, listen: false);
appState = getIt.get<AppState>();
return Scaffold(
backgroundColor: AppColors.bgScaffoldColor,
appBar: AppBar(
title: const Text('Appointments'),
backgroundColor: AppColors.bgScaffoldColor,
),
body: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.medicalFile.tr(context: context).toText22(isBold: true).paddingSymmetrical(24.h, 0.0),
SizedBox(height: 16.h),
TextInputWidget(
labelText: LocaleKeys.search.tr(context: context),
hintText: "Type any record",
controller: TextEditingController(),
keyboardType: TextInputType.number,
isEnable: true,
prefix: null,
autoFocus: false,
isBorderAllowed: false,
isAllowLeadingIcon: true,
padding: EdgeInsets.symmetric(vertical: 8.h, horizontal: 8.h),
leadingIcon: AppAssets.student_card,
).paddingSymmetrical(24.h, 0.0),
SizedBox(height: 16.h),
Container(
width: double.infinity,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 24,
),
child: Padding(
padding: EdgeInsets.all(16.h),
child: Column(
child: Padding(
padding: EdgeInsets.only(top: 80.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.medicalFile.tr(context: context).toText22(isBold: true).paddingSymmetrical(24.h, 0.0),
SizedBox(height: 16.h),
TextInputWidget(
labelText: LocaleKeys.search.tr(context: context),
hintText: "Type any record",
controller: TextEditingController(),
keyboardType: TextInputType.number,
isEnable: true,
prefix: null,
autoFocus: false,
isBorderAllowed: false,
isAllowLeadingIcon: true,
padding: EdgeInsets.symmetric(vertical: 8.h, horizontal: 8.h),
leadingIcon: AppAssets.student_card,
).paddingSymmetrical(24.h, 0.0),
SizedBox(height: 16.h),
Container(
width: double.infinity,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 24,
),
child: Padding(
padding: EdgeInsets.all(16.h),
child: Column(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Image.asset(
appState.getAuthenticatedUser()?.gender == 1 ? AppAssets.male_img : AppAssets.femaleImg,
width: 56.h,
height: 56.h,
),
SizedBox(width: 8.h),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}".toText18(isBold: true),
SizedBox(height: 4.h),
Row(
children: [
CustomButton(
icon: AppAssets.file_icon,
iconColor: AppColors.blackColor,
iconSize: 12.h,
text: "File no: ${appState.getAuthenticatedUser()!.patientId}",
onPressed: () {},
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 10,
fontWeight: FontWeight.normal,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 30.h,
),
SizedBox(width: 4.h),
CustomButton(
text: LocaleKeys.verified.tr(context: context),
onPressed: () {},
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 10,
fontWeight: FontWeight.normal,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 30.h,
),
],
),
],
)
],
),
SizedBox(height: 16.h),
Divider(color: AppColors.dividerColor, height: 1.h),
SizedBox(height: 16.h),
Row(
children: [
CustomButton(
text: "${appState.getAuthenticatedUser()!.age} Years Old",
onPressed: () {},
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 10,
fontWeight: FontWeight.normal,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 30.h,
),
SizedBox(width: 4.h),
CustomButton(
icon: AppAssets.blood_icon,
iconColor: AppColors.primaryRedColor,
iconSize: 13.h,
text: "Blood: ${appState.getUserBloodGroup}",
onPressed: () {},
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 10,
fontWeight: FontWeight.normal,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 30.h,
),
// SizedBox(width: 4.h),
// CustomButton(
// icon: AppAssets.insurance_active_icon,
// iconColor: AppColors.successColor,
// iconSize: 13.h,
// text: "Insurance Active",
// onPressed: () {},
// backgroundColor: AppColors.bgGreenColor.withOpacity(0.20),
// borderColor: AppColors.bgGreenColor.withOpacity(0.0),
// textColor: AppColors.blackColor,
// fontSize: 10,
// fontWeight: FontWeight.normal,
// borderRadius: 12,
// padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
// height: 30.h,
// ),
],
),
SizedBox(height: 8.h),
],
),
),
).paddingSymmetrical(24.h, 0.0),
SizedBox(height: 16.h),
Consumer<MedicalFileViewModel>(builder: (context, medicalFileVM, child) {
return Column(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Image.asset(
appState.getAuthenticatedUser()?.gender == 1 ? AppAssets.male_img : AppAssets.femaleImg,
width: 56.h,
height: 56.h,
),
SizedBox(width: 8.h),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}".toText18(isBold: true),
SizedBox(height: 4.h),
Row(
children: [
CustomButton(
icon: AppAssets.file_icon,
iconColor: AppColors.blackColor,
iconSize: 12.h,
text: "File no: ${appState.getAuthenticatedUser()!.patientId}",
onPressed: () {},
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 10,
fontWeight: FontWeight.normal,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 30.h,
),
SizedBox(width: 4.h),
CustomButton(
text: LocaleKeys.verified.tr(context: context),
onPressed: () {},
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 10,
fontWeight: FontWeight.normal,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 30.h,
),
],
),
],
)
CustomTabBar(
activeTextColor: Color(0xffED1C2B),
activeBackgroundColor: Color(0xffED1C2B).withValues(alpha: .1),
tabs: [
CustomTabBarModel(AppAssets.myFilesBottom, LocaleKeys.general.tr(context: context).needTranslation),
CustomTabBarModel(AppAssets.insurance, LocaleKeys.insurance.tr(context: context)),
CustomTabBarModel(AppAssets.requests, LocaleKeys.request.tr(context: context).needTranslation),
CustomTabBarModel(AppAssets.more, "More".needTranslation),
],
),
SizedBox(height: 16.h),
Divider(color: AppColors.dividerColor, height: 1.h),
SizedBox(height: 16.h),
Row(
children: [
CustomButton(
text: "${appState.getAuthenticatedUser()!.age} Years Old",
onPressed: () {},
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 10,
fontWeight: FontWeight.normal,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 30.h,
),
SizedBox(width: 4.h),
CustomButton(
icon: AppAssets.blood_icon,
iconColor: AppColors.primaryRedColor,
iconSize: 13.h,
text: "Blood: ${appState.getUserBloodGroup}",
onPressed: () {},
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 10,
fontWeight: FontWeight.normal,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 30.h,
),
// SizedBox(width: 4.h),
// CustomButton(
// icon: AppAssets.insurance_active_icon,
// iconColor: AppColors.successColor,
// iconSize: 13.h,
// text: "Insurance Active",
// onPressed: () {},
// backgroundColor: AppColors.bgGreenColor.withOpacity(0.20),
// borderColor: AppColors.bgGreenColor.withOpacity(0.0),
// textColor: AppColors.blackColor,
// fontSize: 10,
// fontWeight: FontWeight.normal,
// borderRadius: 12,
// padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
// height: 30.h,
// ),
],
),
SizedBox(height: 8.h),
onTabChange: (index) {
print(index);
medicalFileVM.onTabChanged(index);
},
).paddingSymmetrical(24.h, 0.0),
SizedBox(height: 24.h),
getSelectedTabData(medicalFileVM.selectedTabIndex),
],
),
),
).paddingSymmetrical(24.h, 0.0),
SizedBox(height: 16.h),
Consumer<MedicalFileViewModel>(builder: (context, medicalFileVM, child) {
return Column(
children: [
CustomTabBar(
activeTextColor: Color(0xffED1C2B),
activeBackgroundColor: Color(0xffED1C2B).withValues(alpha: .1),
tabs: [
CustomTabBarModel(AppAssets.myFilesBottom, LocaleKeys.general.tr(context: context).needTranslation),
CustomTabBarModel(AppAssets.insurance, LocaleKeys.insurance.tr(context: context)),
CustomTabBarModel(AppAssets.requests, LocaleKeys.request.tr(context: context).needTranslation),
CustomTabBarModel(AppAssets.more, "More".needTranslation),
],
onTabChange: (index) {
print(index);
medicalFileVM.onTabChanged(index);
},
).paddingSymmetrical(24.h, 0.0),
SizedBox(height: 24.h),
getSelectedTabData(medicalFileVM.selectedTabIndex),
],
);
}),
],
);
}),
],
),
),
),
);
@ -224,6 +234,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
case 0:
//General Tab Data
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -244,6 +255,179 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
),
);
}),
Consumer<MyAppointmentsViewModel>(builder: (context, myAppointmentsVM, child) {
return SizedBox(
height: 200.h,
child: ListView.separated(
scrollDirection: Axis.horizontal,
padding: EdgeInsets.only(top: 16.h, left: 24.h, right: 24.h, bottom: 0.h),
shrinkWrap: true,
itemCount: myAppointmentsVM.isMyAppointmentsLoading ? 5 : myAppointmentsVM.patientAppointmentsHistoryList.length,
itemBuilder: (context, index) {
return AnimationConfiguration.staggeredList(
position: index,
duration: const Duration(milliseconds: 500),
child: SlideAnimation(
horizontalOffset: 100.0,
child: FadeInAnimation(
child: AnimatedContainer(
duration: Duration(milliseconds: 300),
curve: Curves.easeInOut,
child: myAppointmentsVM.isMyAppointmentsLoading
? MedicalFileAppointmentCard(
patientAppointmentHistoryResponseModel: PatientAppointmentHistoryResponseModel(),
myAppointmentsViewModel: myAppointmentsVM,
)
: MedicalFileAppointmentCard(
patientAppointmentHistoryResponseModel: myAppointmentsVM.patientAppointmentsHistoryList[index],
myAppointmentsViewModel: myAppointmentsViewModel,
),
),
),
),
);
},
separatorBuilder: (BuildContext cxt, int index) => SizedBox(width: 12.h),
),
);
}),
SizedBox(height: 24.h),
"Lab & Radiology".needTranslation.toText18(isBold: true).paddingSymmetrical(24.h, 0.h),
SizedBox(height: 16.h),
Row(
children: [
Expanded(
child: LabRadCard(
icon: AppAssets.lab_result_icon,
labelText: LocaleKeys.labResults.tr(context: context),
labOrderTests: ["Complete blood count", "Creatinine", "Blood Sugar"],
),
),
SizedBox(width: 16.h),
Expanded(
child: LabRadCard(
icon: AppAssets.radiology_icon,
labelText: LocaleKeys.radiology.tr(context: context),
labOrderTests: ["Chest X-ray", "Abdominal Ultrasound", "Dental X-ray"],
),
),
],
).paddingSymmetrical(24.h, 0.h),
SizedBox(height: 24.h),
"Active Medications & Prescriptions".needTranslation.toText18(isBold: true).paddingSymmetrical(24.h, 0.h),
SizedBox(height: 16.h),
Consumer<PrescriptionsViewModel>(builder: (context, prescriptionVM, child) {
return prescriptionVM.isPrescriptionsOrdersLoading
? const MoviesShimmerWidget()
: Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: Colors.white,
borderRadius: 20.h,
),
child: Padding(
padding: EdgeInsets.all(16.h),
child: Column(
children: [
ListView.separated(
itemCount: prescriptionVM.patientPrescriptionOrders.length,
shrinkWrap: true,
padding: const EdgeInsets.only(left: 0, right: 8),
physics: NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
return AnimationConfiguration.staggeredList(
position: index,
duration: const Duration(milliseconds: 500),
child: SlideAnimation(
verticalOffset: 100.0,
child: FadeInAnimation(
child: Row(
children: [
Utils.buildSvgWithAssets(
icon: AppAssets.prescription_item_icon,
width: 40.h,
height: 40.h,
),
SizedBox(width: 8.h),
Row(
mainAxisSize: MainAxisSize.max,
children: [
Column(
children: [
// SizedBox(width: 150.h, child: prescriptionVM.prescriptionDetailsList[index].itemDescription!.toText12(isBold: true, maxLine: 1)),
// SizedBox(
// width: 150.h,
// child:
// "Prescribed By: ${widget.patientAppointmentHistoryResponseModel.doctorTitle} ${widget.patientAppointmentHistoryResponseModel.doctorNameObj}"
// .needTranslation
// .toText10(weight: FontWeight.w500, color: AppColors.greyTextColor, letterSpacing: -0.4),
// ),
],
),
SizedBox(width: 68.h),
Utils.buildSvgWithAssets(
icon: AppAssets.forward_arrow_icon,
iconColor: AppColors.blackColor,
width: 18.h,
height: 13.h,
fit: BoxFit.contain,
),
],
),
],
),
),
),
);
},
separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h),
).onPress(() {
prescriptionVM.setPrescriptionsDetailsLoading();
// Navigator.of(context).push(
// FadePage(
// page: PrescriptionDetailPage(prescriptionsResponseModel: getPrescriptionRequestModel()),
// ),
// );
}),
SizedBox(height: 16.h),
const Divider(color: AppColors.dividerColor),
SizedBox(height: 16.h),
Row(
children: [
Expanded(
child: CustomButton(
text: "All Prescriptions".needTranslation,
onPressed: () {
// Navigator.of(context)
// .push(
// FadePage(
// page: PrescriptionsListPage(),
// ),
// )
// .then((val) {
// prescriptionsViewModel.setPrescriptionsDetailsLoading();
// prescriptionsViewModel.getPrescriptionDetails(getPrescriptionRequestModel());
// });
},
backgroundColor: AppColors.secondaryLightRedColor,
borderColor: AppColors.secondaryLightRedColor,
textColor: AppColors.primaryRedColor,
fontSize: 14,
fontWeight: FontWeight.w500,
borderRadius: 12.h,
height: 40.h,
icon: AppAssets.requests,
iconColor: AppColors.primaryRedColor,
iconSize: 16.h,
),
),
],
),
],
),
),
).paddingSymmetrical(24.h, 0.h);
}),
SizedBox(height: 24.h),
],
);
case 1:

@ -0,0 +1,65 @@
import 'package:flutter/material.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/theme/colors.dart';
class LabRadCard extends StatelessWidget {
LabRadCard({super.key, required this.icon, required this.labelText, required this.labOrderTests});
String icon;
String labelText;
List<String> labOrderTests = [];
@override
Widget build(BuildContext context) {
return Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: false),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Utils.buildSvgWithAssets(
icon: icon,
width: 40.h,
height: 40.h,
fit: BoxFit.contain,
).toShimmer2(isShow: false, radius: 12.h),
SizedBox(width: 8.h),
labelText.toText14(isBold: true).toShimmer2(isShow: false, radius: 6.h, height: 32.h),
],
),
SizedBox(height: 16.h),
ListView.separated(
scrollDirection: Axis.vertical,
padding: EdgeInsets.zero,
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilder: (cxt, index) {
return labOrderTests[index].toText12(isBold: true, maxLine: 1).toShimmer2(isShow: false, radius: 6.h, height: 24.h, width: 120.h);
},
separatorBuilder: (cxt, index) => SizedBox(height: 8.h),
itemCount: labOrderTests.length,
),
SizedBox(height: 16.h),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox.shrink(),
Utils.buildSvgWithAssets(
icon: AppAssets.forward_arrow_icon,
width: 15.h,
height: 15.h,
fit: BoxFit.contain,
iconColor: AppColors.textColor
).toShimmer2(isShow: false, radius: 12.h),
],
)
],
).paddingAll(16.h),
);
}
}

@ -0,0 +1,181 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/utils/date_util.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/features/my_appointments/utils/appointment_type.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/appointments/appointment_details_page.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/transitions/fade_page.dart';
class MedicalFileAppointmentCard extends StatelessWidget {
MedicalFileAppointmentCard({super.key, required this.patientAppointmentHistoryResponseModel, required this.myAppointmentsViewModel});
PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel;
MyAppointmentsViewModel myAppointmentsViewModel;
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CustomButton(
text: DateUtil.formatDateToDate(DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate), false),
onPressed: () {},
backgroundColor: AppointmentType.isArrived(patientAppointmentHistoryResponseModel) ? AppColors.greyColor : AppColors.secondaryLightRedColor,
borderColor: AppointmentType.isArrived(patientAppointmentHistoryResponseModel) ? AppColors.greyLightColor : AppColors.secondaryLightRedColor,
textColor: AppointmentType.isArrived(patientAppointmentHistoryResponseModel) ? AppColors.textColor : AppColors.primaryRedColor,
fontSize: 12,
fontWeight: FontWeight.w500,
borderRadius: 12.h,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 40.h,
icon: AppointmentType.isArrived(patientAppointmentHistoryResponseModel) ? AppAssets.appointment_calendar_icon : AppAssets.alarm_clock_icon,
iconColor: AppointmentType.isArrived(patientAppointmentHistoryResponseModel) ? AppColors.textColor : AppColors.primaryRedColor,
iconSize: 16.h,
).toShimmer2(isShow: myAppointmentsViewModel.isMyAppointmentsLoading),
SizedBox(height: 16.h),
Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true),
width: 200.h,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Image.network(
patientAppointmentHistoryResponseModel.doctorImageURL ?? "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png",
width: 25.h,
height: 27.h,
fit: BoxFit.fill,
).circle(100).toShimmer2(isShow: myAppointmentsViewModel.isMyAppointmentsLoading),
SizedBox(width: 8.h),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
(patientAppointmentHistoryResponseModel.doctorNameObj ?? "").toText14(isBold: true, maxlines: 1).toShimmer2(isShow: myAppointmentsViewModel.isMyAppointmentsLoading),
(patientAppointmentHistoryResponseModel.clinicName ?? "")
.toText12(maxLine: 1, fontWeight: FontWeight.w500, color: AppColors.greyTextColor)
.toShimmer2(isShow: myAppointmentsViewModel.isMyAppointmentsLoading),
],
),
),
],
),
SizedBox(height: 12.h),
Row(
children: [
myAppointmentsViewModel.isMyAppointmentsLoading
? Container().toShimmer2(isShow: true, height: 40.h, width: 100.h, radius: 12.h)
: Expanded(
flex: 6,
child: AppointmentType.isArrived(patientAppointmentHistoryResponseModel)
? getArrivedAppointmentButton(context).toShimmer2(isShow: myAppointmentsViewModel.isMyAppointmentsLoading)
: CustomButton(
text: AppointmentType.getNextActionText(patientAppointmentHistoryResponseModel.nextAction),
onPressed: () {
Navigator.of(context)
.push(FadePage(
page: AppointmentDetailsPage(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel),
))
.then((val) {
// widget.myAppointmentsViewModel.initAppointmentsViewModel();
// widget.myAppointmentsViewModel.getPatientAppointments(true, false);
});
},
backgroundColor: AppointmentType.getNextActionButtonColor(patientAppointmentHistoryResponseModel.nextAction).withOpacity(0.15),
borderColor: AppointmentType.getNextActionButtonColor(patientAppointmentHistoryResponseModel.nextAction).withOpacity(0.01),
textColor: AppointmentType.getNextActionTextColor(patientAppointmentHistoryResponseModel.nextAction),
fontSize: 14,
fontWeight: FontWeight.w500,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 40.h,
icon: AppointmentType.getNextActionIcon(patientAppointmentHistoryResponseModel.nextAction),
iconColor: AppointmentType.getNextActionTextColor(patientAppointmentHistoryResponseModel.nextAction),
iconSize: 14.h,
).toShimmer2(isShow: myAppointmentsViewModel.isMyAppointmentsLoading),
),
SizedBox(width: 8.h),
Expanded(
flex: 2,
child: Container(
height: 40.h,
width: 40.h,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.textColor,
borderRadius: 10.h,
),
child: Padding(
padding: EdgeInsets.all(10.h),
child: Utils.buildSvgWithAssets(
icon: AppAssets.forward_arrow_icon,
width: 10.h,
height: 10.h,
fit: BoxFit.contain,
),
),
).toShimmer2(isShow: myAppointmentsViewModel.isMyAppointmentsLoading).onPress(() {
Navigator.of(context)
.push(
FadePage(
page: AppointmentDetailsPage(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel),
),
)
.then((val) {
// widget.myAppointmentsViewModel.initAppointmentsViewModel();
// widget.myAppointmentsViewModel.getPatientAppointments(true, false);
});
}),
),
],
),
],
).paddingAll(16.h),
),
],
);
}
Widget getArrivedAppointmentButton(BuildContext context) {
return DateTime.now().difference(DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate)).inDays <= 15
? CustomButton(
text: LocaleKeys.askDoctor.tr(context: context),
onPressed: () {},
backgroundColor: AppColors.secondaryLightRedColor,
borderColor: AppColors.secondaryLightRedColor,
textColor: AppColors.primaryRedColor,
fontSize: 14,
fontWeight: FontWeight.w500,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 40.h,
icon: AppAssets.ask_doctor_icon,
iconColor: AppColors.primaryRedColor,
iconSize: 16.h,
)
: CustomButton(
text: "Rebook".needTranslation,
onPressed: () {},
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 14,
fontWeight: FontWeight.w500,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 40.h,
icon: AppAssets.rebook_appointment_icon,
iconColor: AppColors.blackColor,
iconSize: 16.h,
);
}
}
Loading…
Cancel
Save