Merge branch 'master' into dev_aamir

# Conflicts:
#	lib/presentation/medical_file/medical_file_page.dart
#	lib/widgets/chip/app_custom_chip_widget.dart
pull/76/head
aamir-csol 1 month ago
commit 1b652f877d

@ -126,7 +126,7 @@
"gregorianDate": "التاريخ الميلادي", "gregorianDate": "التاريخ الميلادي",
"verifyLoginWith": "يرجى اختيار واحدة من الخيارات التالية للتحقق", "verifyLoginWith": "يرجى اختيار واحدة من الخيارات التالية للتحقق",
"registerUser": "تسجيل", "registerUser": "تسجيل",
"verifyWithFingerprint": "بصمة الإصبع", "verifyWithFingerprint":"البيومترية",
"verifyWithFaceid": "معرف الوجه", "verifyWithFaceid": "معرف الوجه",
"verifyWithSms": "رسالة قصيرة", "verifyWithSms": "رسالة قصيرة",
"verifyWithWhatsapp": "واتساب", "verifyWithWhatsapp": "واتساب",
@ -849,6 +849,7 @@
"pleaseEnterEmail": "يرجى إدخال البريد الإلكتروني", "pleaseEnterEmail": "يرجى إدخال البريد الإلكتروني",
"pleaseEnterAValidEmailFormat": "يرجى إدخال تنسيق بريد إلكتروني صالح", "pleaseEnterAValidEmailFormat": "يرجى إدخال تنسيق بريد إلكتروني صالح",
"selectCountry": "اختر الدولة", "selectCountry": "اختر الدولة",
"forLoginVerification": "للتحقق من تسجيل الدخول" "forLoginVerification": "للتحقق من تسجيل الدخول",
"searchHospital": "بحث في المستشفى"
} }

@ -126,7 +126,7 @@
"gregorianDate": "Gregorian Date", "gregorianDate": "Gregorian Date",
"verifyLoginWith": "Please choose one of the following options to verify", "verifyLoginWith": "Please choose one of the following options to verify",
"registerUser": "Register", "registerUser": "Register",
"verifyWithFingerprint": "Fingerprint", "verifyWithFingerprint": "Biometric",
"verifyWithFaceid": "Face ID", "verifyWithFaceid": "Face ID",
"verifyWithSms": "SMS", "verifyWithSms": "SMS",
"verifyWithWhatsapp": "Whatsapp", "verifyWithWhatsapp": "Whatsapp",
@ -845,5 +845,6 @@
"pleaseEnterAValidEmailFormat": "Please enter a valid email format", "pleaseEnterAValidEmailFormat": "Please enter a valid email format",
"selectCountry": "Select Country", "selectCountry": "Select Country",
"forLoginVerification": "for login verification", "forLoginVerification": "for login verification",
"lastLoginBy": "Last login by" "lastLoginBy": "Last login by",
"searchHospital": "Search Hospital"
} }

@ -22,7 +22,7 @@ extension WidgetExtensions on Widget {
Widget paddingSymmetrical(double horizontal, double vertical) => Padding(padding: EdgeInsets.symmetric(horizontal: horizontal, vertical: vertical), child: this); Widget paddingSymmetrical(double horizontal, double vertical) => Padding(padding: EdgeInsets.symmetric(horizontal: horizontal, vertical: vertical), child: this);
Widget paddingOnly({double left = 0.0, double right = 0.0, double top = 0.0, double bottom = 0.0}) => Widget paddingOnly({double left = 0.0, double right = 0.0, double top = 0.0, double bottom = 0.0}) =>
Padding(padding: EdgeInsets.only(left: left, right: right, top: top, bottom: bottom), child: this); Padding(padding: EdgeInsetsDirectional.only(start: left, end: right, top: top, bottom: bottom), child: this);
Widget toExpanded({int flex = 1}) => Expanded(flex: flex, child: this); Widget toExpanded({int flex = 1}) => Expanded(flex: flex, child: this);

@ -414,11 +414,6 @@ class BookAppointmentsViewModel extends ChangeNotifier {
} }
Future<void> getRegionMappedProjectList() async { Future<void> getRegionMappedProjectList() async {
//todo handle the case in the location is switch on
// if(hospitalList != null && hospitalList!.registeredDoctorMap != null && hospitalList!.registeredDoctorMap!.isNotEmpty){
// filteredHospitalList = hospitalList;
// return;
// }
isRegionListLoading = true; isRegionListLoading = true;
notifyListeners(); notifyListeners();
final result = await bookAppointmentsRepo.getProjectList(); final result = await bookAppointmentsRepo.getProjectList();
@ -432,7 +427,7 @@ class BookAppointmentsViewModel extends ChangeNotifier {
} else if (apiResponse.messageStatus == 1) { } else if (apiResponse.messageStatus == 1) {
var projectList = apiResponse.data!; var projectList = apiResponse.data!;
hospitalList = await DoctorMapper.getMappedHospitals(projectList, hospitalList = await DoctorMapper.getMappedHospitals(projectList,
isArabic: false, isArabic: _appState.isArabic(),
lat: _appState.userLat, lat: _appState.userLat,
lng: _appState.userLong, lng: _appState.userLong,
); );

@ -17,6 +17,8 @@ class LabViewModel extends ChangeNotifier {
List<String> get labSuggestions => _labSuggestionsList; List<String> get labSuggestions => _labSuggestionsList;
Set<TestDetails> uniqueTests = {};
LabViewModel({required this.labRepo, required this.errorHandlerService}); LabViewModel({required this.labRepo, required this.errorHandlerService});
initLabProvider() { initLabProvider() {
@ -32,8 +34,8 @@ class LabViewModel extends ChangeNotifier {
final result = await labRepo.getPatientLabOrders(); final result = await labRepo.getPatientLabOrders();
result.fold( result.fold(
(failure) async => await errorHandlerService.handleError(failure: failure), (failure) async => await errorHandlerService.handleError(failure: failure),
(apiResponse) { (apiResponse) {
if (apiResponse.messageStatus == 2) { if (apiResponse.messageStatus == 2) {
// dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {}); // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
} else if (apiResponse.messageStatus == 1) { } else if (apiResponse.messageStatus == 1) {
@ -43,6 +45,7 @@ class LabViewModel extends ChangeNotifier {
isLabOrdersLoading = false; isLabOrdersLoading = false;
isLabResultsLoading = false; isLabResultsLoading = false;
filterSuggestions(); filterSuggestions();
getUniqueTestDescription();
notifyListeners(); notifyListeners();
if (onSuccess != null) { if (onSuccess != null) {
onSuccess(apiResponse); onSuccess(apiResponse);
@ -75,4 +78,15 @@ class LabViewModel extends ChangeNotifier {
} }
notifyListeners(); notifyListeners();
} }
getUniqueTestDescription() {
uniqueTests = {
for (var item in patientLabOrders)
if (item.testDetails != null)
...?item.testDetails?.map<TestDetails>((test) =>
TestDetails(description: test.description.toString(), testCode: test.testCode.toString(), testID: test.testID, createdOn: item.createdOn))
};
uniqueTests.forEach(print);
}
} }

@ -226,13 +226,14 @@ class TestDetails {
String? description; String? description;
String? testCode; String? testCode;
String? testID; String? testID;
String? createdOn;
TestDetails({this.description, this.testCode, this.testID}); TestDetails({this.description, this.testCode, this.testID, this.createdOn});
TestDetails.fromJson(Map<String, dynamic> json) { TestDetails.fromJson(Map<String, dynamic> json) {
description = json['Description']; description = json['Description'];
testCode = json['TestCode']; testCode = json['TestCode'];
testID = json['TestID']; testID = json['TestID'];
createdOn = json['CreatedOn'];
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
@ -240,6 +241,7 @@ class TestDetails {
data['Description'] = this.description; data['Description'] = this.description;
data['TestCode'] = this.testCode; data['TestCode'] = this.testCode;
data['TestID'] = this.testID; data['TestID'] = this.testID;
data['CreatedOn'] = this.createdOn;
return data; return data;
} }
} }

@ -1,4 +1,5 @@
import 'package:flutter/foundation.dart' show ChangeNotifier; import 'package:flutter/foundation.dart' show ChangeNotifier;
import 'package:hmg_patient_app_new/core/app_state.dart' show AppState;
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/doctor_list_api_response.dart'; import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/doctor_list_api_response.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/select_clinic_page.dart'; import 'package:hmg_patient_app_new/presentation/book_appointment/select_clinic_page.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart'; import 'package:hmg_patient_app_new/services/navigation_service.dart';
@ -20,8 +21,9 @@ class AppointmentViaRegionViewmodel extends ChangeNotifier {
final NavigationService navigationService; final NavigationService navigationService;
AppointmentViaRegionState bottomSheetState = AppointmentViaRegionState bottomSheetState =
AppointmentViaRegionState.REGION_SELECTION; AppointmentViaRegionState.REGION_SELECTION;
final AppState appState;
AppointmentViaRegionViewmodel({required this.navigationService}); AppointmentViaRegionViewmodel({required this.navigationService,required this.appState});
void setSelectedRegionId(String? regionId) { void setSelectedRegionId(String? regionId) {
selectedRegionId = regionId; selectedRegionId = regionId;
@ -69,4 +71,6 @@ class AppointmentViaRegionViewmodel extends ChangeNotifier {
void setHospitalModel(PatientDoctorAppointmentList? hospital) { void setHospitalModel(PatientDoctorAppointmentList? hospital) {
selectedHospital = hospital; selectedHospital = hospital;
} }
bool get isArabic => appState.isArabic();
} }

@ -848,5 +848,6 @@ abstract class LocaleKeys {
static const pleaseEnterAValidEmailFormat = 'pleaseEnterAValidEmailFormat'; static const pleaseEnterAValidEmailFormat = 'pleaseEnterAValidEmailFormat';
static const selectCountry = 'selectCountry'; static const selectCountry = 'selectCountry';
static const forLoginVerification = 'forLoginVerification'; static const forLoginVerification = 'forLoginVerification';
static const searchHospital = 'searchHospital';
} }

@ -147,8 +147,8 @@ void main() async {
), ),
), ),
ChangeNotifierProvider<AppointmentViaRegionViewmodel>( ChangeNotifierProvider<AppointmentViaRegionViewmodel>(
create: (_) => create: (_) => AppointmentViaRegionViewmodel(
AppointmentViaRegionViewmodel(navigationService: getIt())) navigationService: getIt(), appState: getIt()))
], child: MyApp()), ], child: MyApp()),
), ),
); );

@ -38,7 +38,7 @@ class FacilityTypeSelectionWidget extends StatelessWidget {
), ),
), ),
Text( Text(
LocaleKeys.selectFacilitiesSubTitle, LocaleKeys.selectFacilitiesSubTitle.tr(),
style: TextStyle( style: TextStyle(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
@ -55,9 +55,11 @@ class FacilityTypeSelectionWidget extends StatelessWidget {
}), }),
).onPress( ).onPress(
() { () {
regionalViewModel.setFacility(FacilitySelection.HMG.name); if(bookAppointmentViewModel.hospitalList?.registeredDoctorMap?[selectedRegion]?.hmgSize != 0) {
regionalViewModel.setBottomSheetState( regionalViewModel.setFacility(FacilitySelection.HMG.name);
AppointmentViaRegionState.HOSPITAL_SELECTION); regionalViewModel.setBottomSheetState(
AppointmentViaRegionState.HOSPITAL_SELECTION);
}
}, },
), ),
SizedBox(height: 16.h), SizedBox(height: 16.h),
@ -69,9 +71,11 @@ class FacilityTypeSelectionWidget extends StatelessWidget {
"${bookAppointmentViewModel.hospitalList?.registeredDoctorMap?[selectedRegion]?.hmcSize ?? 0}" "${bookAppointmentViewModel.hospitalList?.registeredDoctorMap?[selectedRegion]?.hmcSize ?? 0}"
})).onPress( })).onPress(
() { () {
regionalViewModel.setFacility(FacilitySelection.HMC.name); if(bookAppointmentViewModel.hospitalList?.registeredDoctorMap?[selectedRegion]?.hmcSize!= 0 ) {
regionalViewModel.setBottomSheetState( regionalViewModel.setFacility(FacilitySelection.HMC.name);
AppointmentViaRegionState.HOSPITAL_SELECTION); regionalViewModel.setBottomSheetState(
AppointmentViaRegionState.HOSPITAL_SELECTION);
}
}, },
), ),
], ],

@ -50,7 +50,7 @@ class HospitalBottomSheetBody extends StatelessWidget {
SizedBox(height: 16.h), SizedBox(height: 16.h),
TextInputWidget( TextInputWidget(
labelText: LocaleKeys.search.tr(), labelText: LocaleKeys.search.tr(),
hintText: "Search Hospital".tr(), hintText: LocaleKeys.searchHospital.tr(),
controller: searchText, controller: searchText,
onChange: (value) { onChange: (value) {
appointmentsViewModel.filterHospitalListByString(value, regionalViewModel.selectedRegionId , regionalViewModel.selectedFacilityType == appointmentsViewModel.filterHospitalListByString(value, regionalViewModel.selectedRegionId , regionalViewModel.selectedFacilityType ==

@ -77,7 +77,7 @@ class RegionListItem extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Align( Align(
alignment: Alignment.centerLeft, alignment: AlignmentDirectional.centerStart,
child: Text( child: Text(
title, title,
style: TextStyle( style: TextStyle(

@ -200,7 +200,11 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
void openRegionListBottomSheet(BuildContext context) { void openRegionListBottomSheet(BuildContext context) {
regionalViewModel.flush(); regionalViewModel.flush();
// AppointmentViaRegionViewmodel? viewmodel = null; // AppointmentViaRegionViewmodel? viewmodel = null;
showCommonBottomSheetWithoutHeight(context, title: "", titleWidget: Consumer<AppointmentViaRegionViewmodel>(builder: (_, data, __) => getTitle(data)), isDismissible: false, showCommonBottomSheetWithoutHeight(context,
title: "",
titleWidget: Consumer<AppointmentViaRegionViewmodel>(
builder: (_, data, __) => getTitle(data)),
isDismissible: false,
child: Consumer<AppointmentViaRegionViewmodel>(builder: (_, data, __) { child: Consumer<AppointmentViaRegionViewmodel>(builder: (_, data, __) {
return getRegionalSelectionWidget(data); return getRegionalSelectionWidget(data);
}), callBackFunc: () {}); }), callBackFunc: () {});
@ -234,9 +238,19 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
if (data.selectedRegionId == null) { if (data.selectedRegionId == null) {
return LocaleKeys.selectRegion.tr().toText20(weight: FontWeight.w600); return LocaleKeys.selectRegion.tr().toText20(weight: FontWeight.w600);
} else { } else {
return Utils.buildSvgWithAssets(icon: AppAssets.arrow_back, iconColor: Color(0xff2B353E)).onPress(() { return
data.handleBackPress(); Transform.flip(
}); flipX: data.isArabic ? true : false,
child: Utils.buildSvgWithAssets(
icon: AppAssets.arrow_back,
iconColor: Color(0xff2B353E),
fit: BoxFit.contain,
),
).onPress(() {
data.handleBackPress();
});
} }
} }
} }

@ -0,0 +1,84 @@
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/app_export.dart';
import 'package:hmg_patient_app_new/core/enums.dart';
import 'package:hmg_patient_app_new/core/utils/date_util.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/lab/models/resp_models/patient_lab_orders_response_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.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/chip/app_custom_chip_widget.dart';
import 'package:hmg_patient_app_new/widgets/chip/custom_chip_widget.dart';
class LabOrderByTest extends StatelessWidget {
final VoidCallback onTap;
final int index;
final TestDetails? tests;
final bool isLoading;
final bool isExpanded;
const LabOrderByTest({super.key, required this.onTap, this.tests, required this.index, this.isLoading = false, this.isExpanded = false});
@override
build(BuildContext context) {
return AnimatedContainer(
duration: Duration(milliseconds: 300),
curve: Curves.easeInOut,
margin: EdgeInsets.symmetric(vertical: 8.h),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 20.h, hasShadow: true),
child: InkWell(
onTap: () {
if (!isLoading) {
onTap();
}
},
child: Container(
key: ValueKey<int>(index),
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 8.h),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// ...labOrder!.testDetails!.map((detail) {
Padding(
padding: EdgeInsets.only(bottom: 8.h),
child: '${tests!.description}'.toText14(weight: FontWeight.w500),
),
SizedBox(height: 12.h),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
AppCustomChipWidget(
richText: '${"Last Tested:".needTranslation} ${ DateUtil.formatDateToDate(DateUtil.convertStringToDate(tests!.createdOn), false)}'.toText12(isBold: true),
// chipType: ChipTypeEnum.lightBg,
backgroundColor: AppColors.greyLightColor,
textColor: AppColors.textColor,
// borderRadius: 5,
),
CustomButton(
icon: AppAssets.view_report_icon,
iconColor: AppColors.primaryRedColor,
iconSize: 16.h,
text: LocaleKeys.viewReport.tr(context: context),
onPressed: () {},
backgroundColor: AppColors.secondaryLightRedColor,
borderColor: AppColors.secondaryLightRedColor,
textColor: AppColors.primaryRedColor,
fontSize: 14,
fontWeight: FontWeight.bold,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 40.h,
),
],
),
],
),
)));
}
}

@ -11,6 +11,7 @@ import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/lab/models/resp_models/patient_lab_orders_response_model.dart'; import 'package:hmg_patient_app_new/features/lab/models/resp_models/patient_lab_orders_response_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/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_order_by_test.dart';
import 'package:hmg_patient_app_new/presentation/lab/lab_result_item_view.dart'; import 'package:hmg_patient_app_new/presentation/lab/lab_result_item_view.dart';
import 'package:hmg_patient_app_new/presentation/lab/search_lab_report.dart'; import 'package:hmg_patient_app_new/presentation/lab/search_lab_report.dart';
import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/theme/colors.dart';
@ -32,7 +33,7 @@ class _LabOrdersPageState extends State<LabOrdersPage> {
List<List<TestDetails>?> labSuggestions = []; List<List<TestDetails>?> labSuggestions = [];
int? expandedIndex; int? expandedIndex;
String? selectedFilterText = ''; String? selectedFilterText = '';
int activeIndex = 0;
@override @override
void initState() { void initState() {
scheduleMicrotask(() { scheduleMicrotask(() {
@ -78,7 +79,10 @@ class _LabOrdersPageState extends State<LabOrdersPage> {
// CustomTabBarModel(null, "Completed".needTranslation), // CustomTabBarModel(null, "Completed".needTranslation),
], ],
onTabChange: (index) { onTabChange: (index) {
// myAppointmentsViewModel.onTabChange(index); activeIndex = index;
setState(() {
});
}, },
), ),
SizedBox(height: 16.h), SizedBox(height: 16.h),
@ -89,39 +93,73 @@ class _LabOrdersPageState extends State<LabOrdersPage> {
isSelected: true, isSelected: true,
) )
: SizedBox(), : SizedBox(),
ListView.builder( activeIndex == 0
shrinkWrap: true, ? ListView.builder(
physics: NeverScrollableScrollPhysics(), shrinkWrap: true,
padding: EdgeInsets.zero, physics: NeverScrollableScrollPhysics(),
itemCount: model.isLabOrdersLoading ? 5 : model.patientLabOrders.length, padding: EdgeInsets.zero,
itemBuilder: (context, index) { itemCount: model.isLabOrdersLoading ? 5 : model.patientLabOrders.length,
final isExpanded = expandedIndex == index; itemBuilder: (context, index) {
return model.isLabOrdersLoading final isExpanded = expandedIndex == index;
? LabResultItemView( return model.isLabOrdersLoading
? LabResultItemView(
onTap: () {},
labOrder: null,
index: index,
isLoading: true,
)
: AnimationConfiguration.staggeredList(
position: index,
duration: const Duration(milliseconds: 500),
child: SlideAnimation(
verticalOffset: 100.0,
child: FadeInAnimation(
child: LabResultItemView(
onTap: () {
setState(() {
expandedIndex = isExpanded ? null : index;
});
},
labOrder: model.patientLabOrders[index],
index: index,
isExpanded: isExpanded)),
),
);
},
)
: ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
padding: EdgeInsets.zero,
itemCount: model.isLabOrdersLoading ? 5 :model.uniqueTests.toList().length,
itemBuilder: (context, index) {
final isExpanded = expandedIndex == index;
return model.isLabOrdersLoading
? LabResultItemView(
onTap: () {}, onTap: () {},
labOrder: null, labOrder: null,
index: index, index: index,
isLoading: true, isLoading: true,
) ) : AnimationConfiguration.staggeredList(
: AnimationConfiguration.staggeredList( position: index,
position: index, duration: const Duration(milliseconds: 500),
duration: const Duration(milliseconds: 500), child: SlideAnimation(
child: SlideAnimation( verticalOffset: 100.0,
verticalOffset: 100.0, child: FadeInAnimation(
child: FadeInAnimation( child: LabOrderByTest(
child: LabResultItemView( onTap: () {
onTap: () { setState(() {
setState(() { expandedIndex = isExpanded ? null : index;
expandedIndex = isExpanded ? null : index; });
}); },
}, tests: model.uniqueTests.toList()[index],
labOrder: model.patientLabOrders[index], index: index,
index: index, isExpanded: isExpanded)),
isExpanded: isExpanded)), ),
), );
);
}, },
), )
], ],
); );
}, },

@ -776,4 +776,9 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
return Container(); return Container();
} }
} }
getMember() {
// AuthanticationViewModel authanticationViewModel = getIt.get<AuthanticationViewModel>();
// RequestUtils.getAddFamilyRequest(nationalIDorFile: nationalIDorFile, mobileNo: mobileNo, countryCode: countryCode, loginType: loginType);
}
} }

Loading…
Cancel
Save