diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 348eade4..a2c9d445 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -2024,7 +2024,7 @@ const Map localizedValues = { "hospitalNavigationSubtitle": {"en": "Navigation", "ar": "المستشفى"}, "continueAgreeTerms": {"en": "By continuing, You agree to the above Terms and Conditions.", "ar": "من خلال المتابعة، فإنك توافق على الشروط والأحكام المذكورة أعلاه."}, "agreeText": {"en": "Agree", "ar": "أوافق"}, - "ERCheckInSuccess": {"en": "Your ER Online Check-In has been successfully done.", "ar": "لقد تم تسجيل وصولك للطوارئ عبر الإنترنت بنجاح."}, + "ERCheckInSuccess": {"en": "Your ER Online Check-In has been successfully done. Please proceed to the waiting area.", "ar": "لقد تم تسجيل دخولك عبر الإنترنت بنجاح. يرجى التوجه إلى منطقة الانتظار."}, "generalConsent": {"en": "General Consent: ", "ar": "موافقة عامة:"}, "generalConsent1": { diff --git a/lib/pages/ErService/EROnlineCheckIn/EROnlineCheckInHome.dart b/lib/pages/ErService/EROnlineCheckIn/EROnlineCheckInHome.dart index bca3a0b0..f56e8a29 100644 --- a/lib/pages/ErService/EROnlineCheckIn/EROnlineCheckInHome.dart +++ b/lib/pages/ErService/EROnlineCheckIn/EROnlineCheckInHome.dart @@ -1,6 +1,8 @@ +import 'package:barcode_scan2/barcode_scan2.dart'; import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/ErService/EROnlineCheckIn/EROnlineCheckInBookAppointment.dart'; +import 'package:diplomaticquarterapp/pages/ErService/EROnlineCheckIn/EROnlineCheckInNFCQRCLocation.dart'; import 'package:diplomaticquarterapp/pages/ErService/EROnlineCheckIn/EROnlineCheckInPaymentDetails.dart'; import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; @@ -11,6 +13,7 @@ import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/location_util.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/bottom_options/bottom_sheet.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/nfc/nfc_reader_sheet.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; @@ -288,22 +291,76 @@ class _EROnlineCheckInHomePageState extends State with child: DefaultButton( TranslationBase.of(context).arrived, () { - if (_supportsNFC) { - Future.delayed(const Duration(milliseconds: 500), () { - showNfcReader(context, onNcfScan: (String nfcId) { - Future.delayed(const Duration(milliseconds: 100), () { - print(nfcId); - getProjectIDFromNFC(nfcId, true); - // Navigator.push(context, FadePage(page: EROnlineCheckInPaymentDetails())); - }); - }, onCancel: () { - Navigator.of(context).pop(); - }); - }); - } else { - //NFCNotSupported - AppToast.showErrorToast(message: TranslationBase.of(context).NFCNotSupported); - } + showMyBottomSheet(context, + callBackFunc: () {}, + child: Padding( + padding: const EdgeInsets.all(21.0), + child: Column( + children: [ + Text(TranslationBase.of(context).scanQRHospital, + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + )), + mHeight(21), + GridView( + physics: const NeverScrollableScrollPhysics(), + shrinkWrap: true, + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: (MediaQuery.of(context).size.width < 550) ? 3 : 5, childAspectRatio: 1 / 1, crossAxisSpacing: 8, mainAxisSpacing: 12), + children: [ + attendanceMethod(TranslationBase.of(context).scanNFC, "assets/images/nfc/contactless.svg", true, () { + if (_supportsNFC) { + Future.delayed(const Duration(milliseconds: 500), () { + showNfcReader(context, onNcfScan: (String nfcId) { + Future.delayed(const Duration(milliseconds: 100), () { + print(nfcId); + getProjectIDFromNFC(nfcId, true); + // Navigator.push(context, FadePage(page: EROnlineCheckInPaymentDetails())); + }); + }, onCancel: () { + Navigator.of(context).pop(); + }); + }); + } else { + //NFCNotSupported + AppToast.showErrorToast(message: TranslationBase.of(context).NFCNotSupported); + } + }), + attendanceMethod(TranslationBase.of(context).pharmaLiveCareScanQR, "assets/images/new/services/qr_code.svg", true, () async { + String onlineCheckInQRCode = (await BarcodeScanner.scan().then((value) => value.rawContent)); + if (onlineCheckInQRCode != "") { + print(onlineCheckInQRCode); + getProjectIDFromNFC(onlineCheckInQRCode, true); + // sendNfcCheckInRequest(onlineCheckInQRCode, 2); + } else {} + }), + attendanceMethod(TranslationBase.of(context).checkInViaLocation, "assets/images/new/services/location.svg", true, () {}) + ], + ), + ], + ), + )); + + // Navigator.push(context, FadePage(page: EROnlineCheckInNFCQRLocation(projectID: 15))).then((value) {}); + + // if (_supportsNFC) { + // Future.delayed(const Duration(milliseconds: 500), () { + // showNfcReader(context, onNcfScan: (String nfcId) { + // Future.delayed(const Duration(milliseconds: 100), () { + // print(nfcId); + // getProjectIDFromNFC(nfcId, true); + // // Navigator.push(context, FadePage(page: EROnlineCheckInPaymentDetails())); + // }); + // }, onCancel: () { + // Navigator.of(context).pop(); + // }); + // }); + // } else { + // //NFCNotSupported + // AppToast.showErrorToast(message: TranslationBase.of(context).NFCNotSupported); + // } }, color: CustomColors.accentColor, ), @@ -315,6 +372,8 @@ class _EROnlineCheckInHomePageState extends State with child: DefaultButton( TranslationBase.of(context).checkinOptions, () { + // Navigator.push(context, FadePage(page: EROnlineCheckInNFCQRLocation(projectID: 15))).then((value) {}); + if (_supportsNFC) { Future.delayed(const Duration(milliseconds: 500), () { showNfcReader(context, onNcfScan: (String nfcId) { @@ -439,6 +498,46 @@ class _EROnlineCheckInHomePageState extends State with }); } + Widget markCheckInWidget() { + return GridView( + physics: const NeverScrollableScrollPhysics(), + shrinkWrap: true, + padding: const EdgeInsets.only(bottom: 0, top: 21), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: (MediaQuery.of(context).size.width < 550) ? 3 : 5, childAspectRatio: 1 / 1, crossAxisSpacing: 8, mainAxisSpacing: 8), + children: [], + ); + } + + Widget attendanceMethod(String title, String image, bool isEnabled, VoidCallback onPress) => InkWell( + onTap: () { + Navigator.pop(context); + onPress(); + }, + child: Container( + decoration: containerColorRadiusBorderWidth(Colors.white, 15, CustomColors.darkGreyColor, 1), + clipBehavior: Clip.antiAlias, + padding: const EdgeInsets.only(left: 10, right: 10, top: 14, bottom: 14), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded(child: SvgPicture.asset(image, color: Colors.black, alignment: Alignment.topLeft)), + Text( + title, + style: TextStyle(color: Colors.black, fontSize: 14, letterSpacing: -0.68, fontWeight: FontWeight.bold), + ), + // title.toText17(isBold: true, color: Colors.white), + ], + ), + ), + ); + + // .onPress( + // () { + // if (!isEnabled) return; + // onPress(); + // }, + // ); + void checkPatientERAdvanceBalance() { locationUtils.getCurrentLocation(); GifLoaderDialogUtils.showMyDialog(context); diff --git a/lib/pages/ErService/EROnlineCheckIn/EROnlineCheckInNFCQRCLocation.dart b/lib/pages/ErService/EROnlineCheckIn/EROnlineCheckInNFCQRCLocation.dart new file mode 100644 index 00000000..d3f1e20f --- /dev/null +++ b/lib/pages/ErService/EROnlineCheckIn/EROnlineCheckInNFCQRCLocation.dart @@ -0,0 +1,374 @@ +import 'dart:typed_data'; + +import 'package:barcode_scan2/barcode_scan2.dart'; +import 'package:diplomaticquarterapp/analytics/google-analytics.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/model/privilege/ProjectDetailListModel.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/models/Appointments/PatientShareResposne.dart'; +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; +import 'package:diplomaticquarterapp/models/header_model.dart'; +import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; +import 'package:diplomaticquarterapp/routes.dart'; +import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/location_util.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/custom_text_button.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/medical/medical_profile_item.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; +import 'package:diplomaticquarterapp/widgets/new_design/doctor_header.dart'; +import 'package:diplomaticquarterapp/widgets/nfc/nfc_reader_sheet.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_nfc_kit/flutter_nfc_kit.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:provider/provider.dart'; + +class EROnlineCheckInNFCQRLocation extends StatefulWidget { + // late PatientShareResponse? patientShareResponse; + // late AppoitmentAllHistoryResultList? appointment; + // late String? appoQR; + // AuthenticatedUser? authUser; + // AppSharedPreferences sharedPref = AppSharedPreferences(); + + int projectID; + + EROnlineCheckInNFCQRLocation({required this.projectID}); + + @override + _EROnlineCheckInNFCQRLocationState createState() => _EROnlineCheckInNFCQRLocationState(); +} + +class _EROnlineCheckInNFCQRLocationState extends State { + late Uint8List _bytes; + bool _supportsNFC = false; + late BuildContext _context; + + late ProjectViewModel projectViewModel; + late LocationUtils locationUtils; + ProjectDetailListModel projectDetailListModel = ProjectDetailListModel(); + + @override + void initState() { + super.initState(); + } + + startNFCScan() { + Future.delayed(const Duration(milliseconds: 500), () { + showNfcReader(context, onNcfScan: (String nfcId) { + Future.delayed(const Duration(milliseconds: 100), () { + sendNfcCheckInRequest(nfcId, 2); + }); + }, onCancel: () { + // Navigator.of(context).pop(); + }); + }); + } + + startQRCodeScan() async { + String onlineCheckInQRCode = (await BarcodeScanner.scan().then((value) => value.rawContent)); + if (onlineCheckInQRCode != "") { + sendNfcCheckInRequest(onlineCheckInQRCode, 2); + } else {} + } + + startLocationCheckIn() async { + GifLoaderDialogUtils.showMyDialog(context); + locationUtils = new LocationUtils(isShowConfirmDialog: true, context: context); + locationUtils.getCurrentLocation(callBack: (value) { + projectDetailListModel = Utils.getProjectDetailObj(projectViewModel, widget.projectID); + double dist = Utils.distance(value.latitude, value.longitude, double.parse(projectDetailListModel.latitude!), double.parse(projectDetailListModel.longitude!)).ceilToDouble() * 1000; + print(dist); + if (dist <= projectDetailListModel.geofenceRadius!) { + sendNfcCheckInRequest(projectDetailListModel.checkInQrCode!, 2); + } else { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: TranslationBase.of(context).locationCheckInError); + } + }); + } + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + _context = context; + FlutterNfcKit.nfcAvailability.then((value) { + _supportsNFC = (value == NFCAvailability.available); + }); + List checkInOptionsList = getCheckInOptionsList(context); + return AppScaffold( + appBarTitle: TranslationBase.of(context).onlineCheckIn, + isShowAppBar: true, + showNewAppBar: true, + showNewAppBarTitle: true, + body: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // DoctorHeader( + // headerModel: HeaderModel( + // widget.appointment!.doctorTitle! + " " + widget.appointment!.doctorNameObj!, + // widget.appointment!.doctorID ?? 0, + // widget.appointment!.doctorImageURL!, + // widget.appointment!.doctorSpeciality!, + // "", + // widget.appointment!.projectName!, + // DateUtil.convertStringToDate(widget.appointment!.appointmentDate!), + // widget.appointment!.isLiveCareAppointment! + // ? DateUtil.convertStringToDate(widget.appointment!.appointmentDate!).toString().split(" ")[1].substring(0, 5) + // : widget.appointment!.startTime!.substring(0, 5), + // "null", + // widget.appointment!.doctorRate, + // widget.appointment!.actualDoctorRate, + // widget.appointment!.noOfPatientsRate, + // "", + // ), + // isShowName: true, + // isNeedToShowButton: false, + // buttonTitle: '', + // onTap: () {}, + // onRatingAndReviewTap: () {}, + // ), + InkWell( + child: Container( + margin: EdgeInsets.only(top: 30.0), + padding: EdgeInsets.all(8), + child: SvgPicture.asset( + "assets/images/nfc/contactless.svg", + width: 80.0, + height: 80.0, + ), + ), + onTap: () { + showNfcReader(context, onNcfScan: (String nfcId) { + Future.delayed(const Duration(milliseconds: 100), () { + sendNfcCheckInRequest(nfcId, 2); + }); + }, onCancel: () { + // Navigator.of(context).pop(); + }); + }, + ), + Row( + children: [ + Expanded( + child: Container( + width: double.infinity, + margin: EdgeInsets.only(top: 15.0, bottom: 10.0, left: 20.0, right: 20.0), + child: Text(TranslationBase.of(context).scanQRHospital, + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + )), + ), + ), + ], + ), + mHeight(21), + Padding( + padding: EdgeInsets.only(left: 21, right: 21), + child: GridView.builder( + shrinkWrap: true, + primary: false, + physics: NeverScrollableScrollPhysics(), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, childAspectRatio: 2 / 2, crossAxisSpacing: 12, mainAxisSpacing: 12), + padding: EdgeInsets.zero, + itemCount: checkInOptionsList.length, + itemBuilder: (BuildContext context, int index) { + return checkInOptionsList[index]; + }, + ), + ), + ], + ), + ), + // bottomSheet: Container( + // color: CustomColors.appBackgroudGreyColor, + // padding: EdgeInsets.all(21), + // // height: 45.0, + // child: Row( + // children: [ + // Expanded( + // flex: 1, + // child: ButtonTheme( + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(10.0), + // ), + // height: 45.0, + // child: CustomTextButton( + // backgroundColor: CustomColors.green, + // elevation: 0, + // onPressed: () { + // startNFCScan(); + // }, + // child: Text(TranslationBase.of(context).scanNFC, + // style: TextStyle( + // fontSize: 18.0, + // color: Colors.white, + // )), + // ), + // ), + // ), + // ], + // ), + // ), + ); + } + + List getCheckInOptionsList(BuildContext context) { + List optionsList = []; + + optionsList.add( + InkWell( + onTap: () { + if (projectViewModel.havePrivilege(102)) { + startLocationCheckIn(); + } + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).checkInViaLocation, + imagePath: 'location.svg', + subTitle: "", + isEnable: projectViewModel.havePrivilege(102), + width: 70.0, + height: 70.0, + ), + ), + ); + + optionsList.add( + InkWell( + onTap: () { + if (projectViewModel.havePrivilege(79)) { + startQRCodeScan(); + } + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).pharmaLiveCareScanQR, + imagePath: 'qr_code.svg', + subTitle: "", + isEnable: projectViewModel.havePrivilege(79), + width: 80.0, + height: 80.0, + ), + ), + ); + + optionsList.add( + InkWell( + onTap: () { + if (projectViewModel.havePrivilege(80) && _supportsNFC) { + startNFCScan(); + } else { + Utils.showErrorToast(TranslationBase.of(context).NFCNotSupported); + } + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).scanNFC, + imagePath: 'contactless.svg', + subTitle: "", + isEnable: projectViewModel.havePrivilege(80), + width: 80.0, + height: 80.0, + ), + ), + ); + + return optionsList; + } + + Future navigateToHome(context) async { + Navigator.of(context).pushNamed(HOME); + } + + getPatientShare(context, String appointmentNo, int clinicID, int projectID, DoctorList docObject) {} + + String getDate(String appoDate) { + var appoDateFormatted = ""; + + var dateObj = DateUtil.convertStringToDate(appoDate); + + setState(() { + appoDateFormatted = DateUtil.getWeekDay(dateObj.weekday) + + ", " + + dateObj.day.toString() + + " " + + DateUtil.getMonth(dateObj.month) + + " " + + dateObj.year.toString() + + ", " + + dateObj.hour.toString() + + ":" + + dateObj.minute.toString() + + ":00"; + }); + + return appoDateFormatted; + } + + String getDoctorSpeciality(List docSpecial) { + String docSpeciality = ""; + if (docSpecial != null && docSpecial.length != 0) { + docSpecial.forEach((v) { + docSpeciality = docSpeciality + v + "\n"; + }); + } + return docSpeciality; + } + + sendNfcCheckInRequest(String nfcId, int checkInBy) { + GifLoaderDialogUtils.showMyDialog(context); + + DoctorsListService service = new DoctorsListService(); + + // service.sendCheckinNfcRequest(widget!.patientShareResponse!.appointmentNo!, nfcId, widget.patientShareResponse!.projectID!, checkInBy, widget.patientShareResponse!.clinicID!, context).then((res) { + // print(res); + // + // GifLoaderDialogUtils.hideDialog(context); + // _showMyDialog(res["SuccessMsg"], this.context); + // }).catchError((err) { + // GifLoaderDialogUtils.hideDialog(context); + // print(err); + // _showMyDialog(err, this.context); + // }); + } + + Future _showMyDialog(String message, BuildContext context) async { + return showDialog( + context: context, + barrierDismissible: true, // user must tap button! + builder: (BuildContext context) { + return AlertDialog( + title: const Text('Alert'), + content: SingleChildScrollView( + child: ListBody( + children: [ + Text(message), + ], + ), + ), + actions: [ + TextButton( + child: const Text('OK'), + onPressed: () { + Navigator.of(context).pop(); + Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (context) => LandingPage()), (Route r) => false); + }, + ), + ], + ); + }, + ); + } +} diff --git a/lib/pages/ErService/EROnlineCheckIn/EROnlineCheckInPaymentDetails.dart b/lib/pages/ErService/EROnlineCheckIn/EROnlineCheckInPaymentDetails.dart index 13e5c733..a9873df4 100644 --- a/lib/pages/ErService/EROnlineCheckIn/EROnlineCheckInPaymentDetails.dart +++ b/lib/pages/ErService/EROnlineCheckIn/EROnlineCheckInPaymentDetails.dart @@ -521,9 +521,10 @@ class _EROnlineCheckInPaymentDetailsState extends State LandingPage()), (Route r) => false); } else { autoGenerateInvoiceER(paymentRes); } diff --git a/lib/widgets/bottom_options/bottom_sheet.dart b/lib/widgets/bottom_options/bottom_sheet.dart new file mode 100644 index 00000000..c59c565e --- /dev/null +++ b/lib/widgets/bottom_options/bottom_sheet.dart @@ -0,0 +1,89 @@ +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:flutter/material.dart'; + +void showMyBottomSheet(BuildContext context, {required Widget child, required VoidCallback callBackFunc, String? type}) { + showModalBottomSheet( + context: context, + isScrollControlled: true, + backgroundColor: Colors.transparent, + builder: (BuildContext context) { + return Container( + constraints: BoxConstraints( + maxHeight: type =='CONTINUE_ACTION' ? MediaQuery.of(context).size.height *.75 : double.infinity,), + decoration: const BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only( + topRight: Radius.circular(25), + topLeft: Radius.circular(25), + ), + ), + padding: MediaQuery.of(context).viewInsets, + clipBehavior: Clip.antiAlias, + child:SingleChildScrollView(child: Column( + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + mHeight(13), + Container( + height: 6, + width: 60, + decoration: const BoxDecoration( + color: Color(0xff9A9A9A), + borderRadius: BorderRadius.all( + Radius.circular(20), + ), + ), + ), + mHeight(8), + child, + ], + )), + ); + }, + ).then((value) { + // print("BACK FROM DELEGATE!!!!"); + // print("value: $value"); + if (value == "delegate_reload") { + callBackFunc(); + } + }); +} + +class BottomSheetItem extends StatelessWidget { + final Function onTap; + final IconData icon; + final String title; + final Color color; + + const BottomSheetItem({Key? key, required this.onTap, required this.title, required this.icon, this.color = Colors.black}) : super(key: key); + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: () { + if (onTap != null) { + Navigator.pop(context); + onTap(); + } + }, + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 18.0, vertical: 18.0), + child: Row( + children: [ + if (icon != null) + Icon( + icon, + color: color, + size: 18.0, + ), + if (icon != null) SizedBox(width: 24.0), + Text( + title ?? "", + style: TextStyle(color: color), + ), + ], + ), + ), + ); + } +}