From 7280e2a1d7e86276c2cc7835e7a0c262b2eab3aa Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Thu, 25 May 2023 12:45:02 +0300 Subject: [PATCH] Birth Notification UI Implemented --- lib/config/localized_values.dart | 70 +++-- .../InPatientServices/birth_notification.dart | 273 ++++++++++++++++++ .../InPatientServices/inpatient_home.dart | 3 +- .../AttachInsuranceCardImageDialog.dart | 43 +-- lib/uitl/translations_delegate_base.dart | 9 + lib/widgets/bottom_options/BottomSheet.dart | 2 +- 6 files changed, 355 insertions(+), 45 deletions(-) create mode 100644 lib/pages/InPatientServices/birth_notification.dart diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 5580da41..a81a5320 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -1844,39 +1844,51 @@ const Map localizedValues = { "privacyPolicy": {"en": "Privacy Policy", "ar": "سياسة الخصوصية"}, "termsConditions": {"en": "Terms & Conditions", "ar": "الأحكام والشروط"}, "prescriptionDeliveryError": {"en": "This clinic does not support refill & delivery.", "ar": "هذه العيادة لا تدعم إعادة التعبئة والتسليم."}, - "liveCarePermissions": {"en": "LiveCare requires Camera, Microphone & Location permissions to enable virtual consultation between patient & doctor, Please allow these to proceed.", "ar": "يتطلب لايف كير أذونات الكاميرا والميكروفون والموقع، يرجى السماح لها بالمتابعة."}, - "lakumUnhold": { "en": "The account has already been activated", "ar": "لقد تم تفعيل الحساب من قبل" }, - "lakumDiscontinue": { "en": "The account is closed", "ar": "الحساب مغلق" }, - "lakumSuccess": { "en": "The account has been activated successfully", "ar": "تم تفعيل الحساب بنجاح" }, - "deleteAccount": { "en": "Deactivate Account", "ar": "ايقاف الحساب مؤقتاً" }, - "deactivateAccount": { "en": "Are you sure you want to deactivate your account?", "ar": "هل أنت متأكد أنك تريد ايقاف الحساب مؤقتاً حسابك؟" }, - "accountDeactivated": { "en": "Your account has been deactivated successfully", "ar": "تم ايقاف الحساب مؤقتاً بنجاح." }, - "accountDeactivatedMsg": { "en": "Your account has been deactivated. Would you like to reactivate it?", "ar": "حسابك معطل. هل ترغب في إعادة تنشيطه مرة أخرى؟" }, - "updateInsuranceManually": { "en": "Update Insurance Manually", "ar": "تحديث التأمين يدويا" }, - "or": { "en": "Update Insurance Manually", "ar": "تحديث التأمين يدويا" }, - "enterInsuranceDetails": { "en": "Please enter your insurance card details below:", "ar": "الرجاء إدخال تفاصيل بطاقة التأمين الخاصة بك أدناه:" }, - "cardHolderName": { "en": "Card Holder Name", "ar": "إسم صاحب البطاقة" }, - "membershipNo": { "en": "Membership No.", "ar": "رقم العضوية" }, - "policyNo": { "en": "Policy No.", "ar": "رقم وثيقة التأمين" }, - "paymentOnly": { "en": "Payment", "ar": "معلقة" }, - "pendingOnly": { "en": "Pending", "ar": "مدفوعات" }, - "insuranceClassName": { "en": "Insurance Class", "ar": "فئة التأمين" }, - "insuranceRequestSubmit": { "en": "Your insurance update request has been submitted successfully.", "ar": "تم تقديم طلب تحديث التأمين الخاص بك بنجاح." }, - "NFCNotSupported": { "en": "Your device does not support NFC. Please visit reception to Check-In", "ar": "جهازك لا يدعم NFC. يرجى زيارة مكتب الاستقبال لتسجيل الوصول" }, + "liveCarePermissions": { + "en": "LiveCare requires Camera, Microphone & Location permissions to enable virtual consultation between patient & doctor, Please allow these to proceed.", + "ar": "يتطلب لايف كير أذونات الكاميرا والميكروفون والموقع، يرجى السماح لها بالمتابعة." + }, + "lakumUnhold": {"en": "The account has already been activated", "ar": "لقد تم تفعيل الحساب من قبل"}, + "lakumDiscontinue": {"en": "The account is closed", "ar": "الحساب مغلق"}, + "lakumSuccess": {"en": "The account has been activated successfully", "ar": "تم تفعيل الحساب بنجاح"}, + "deleteAccount": {"en": "Deactivate Account", "ar": "ايقاف الحساب مؤقتاً"}, + "deactivateAccount": {"en": "Are you sure you want to deactivate your account?", "ar": "هل أنت متأكد أنك تريد ايقاف الحساب مؤقتاً حسابك؟"}, + "accountDeactivated": {"en": "Your account has been deactivated successfully", "ar": "تم ايقاف الحساب مؤقتاً بنجاح."}, + "accountDeactivatedMsg": {"en": "Your account has been deactivated. Would you like to reactivate it?", "ar": "حسابك معطل. هل ترغب في إعادة تنشيطه مرة أخرى؟"}, + "updateInsuranceManually": {"en": "Update Insurance Manually", "ar": "تحديث التأمين يدويا"}, + "or": {"en": "Update Insurance Manually", "ar": "تحديث التأمين يدويا"}, + "enterInsuranceDetails": {"en": "Please enter your insurance card details below:", "ar": "الرجاء إدخال تفاصيل بطاقة التأمين الخاصة بك أدناه:"}, + "cardHolderName": {"en": "Card Holder Name", "ar": "إسم صاحب البطاقة"}, + "membershipNo": {"en": "Membership No.", "ar": "رقم العضوية"}, + "policyNo": {"en": "Policy No.", "ar": "رقم وثيقة التأمين"}, + "paymentOnly": {"en": "Payment", "ar": "معلقة"}, + "pendingOnly": {"en": "Pending", "ar": "مدفوعات"}, + "insuranceClassName": {"en": "Insurance Class", "ar": "فئة التأمين"}, + "insuranceRequestSubmit": {"en": "Your insurance update request has been submitted successfully.", "ar": "تم تقديم طلب تحديث التأمين الخاص بك بنجاح."}, + "NFCNotSupported": {"en": "Your device does not support NFC. Please visit reception to Check-In", "ar": "جهازك لا يدعم NFC. يرجى زيارة مكتب الاستقبال لتسجيل الوصول"}, "enter-workplace-name": {"en": "Please enter your workplace name:", "ar": "رجاء إدخال مكان العمل:"}, "workplaceName": {"en": "Workplace name:", "ar": "مكان العمل:"}, "callLiveCareSupport": {"en": "Call LiveCare Support", "ar": "اتصل بدعم اللايف كير"}, - "needApproval": {"en": "Your sick leave is under process in medical administration, you will be notified once approved.", "ar": "جازتك المرضية تحت الإجراء في الإدارة الطبية ، سوف يتم إشعارك فور الموافقه عليها."}, + "needApproval": { + "en": "Your sick leave is under process in medical administration, you will be notified once approved.", + "ar": "جازتك المرضية تحت الإجراء في الإدارة الطبية ، سوف يتم إشعارك فور الموافقه عليها." + }, "pendingActivation": {"en": "Pending Activation", "ar": "في انتظار التنشيط"}, "awaitingApproval": {"en": "Awaiting Approval", "ar": "انتظر القبول"}, "liveCareSupportContact": {"en": "LiveCare Support Contact: ", "ar": "اتصل لايف كير: "}, "pharmaLiveCare": {"en": "Pharma LiveCare", "ar": "لايف كير الصيدلية"}, "pharmaLiveCare1": {"en": "What is Pharma LiveCare?", "ar": "ما هولايف كير الصيدلية؟"}, - "pharmaLiveCareDesc1": {"en": "Pharma LiveCare allows you to get consultation from your doctor virtually being in HMG Pharmacy booth.", "ar": "تتيح لك خدمة لايف كير الصيدلية الحصول على استشارة من طبيبك المتواجد فعليًا في كشك صيدلية د.سليمان الحبيب."}, + "pharmaLiveCareDesc1": { + "en": "Pharma LiveCare allows you to get consultation from your doctor virtually being in HMG Pharmacy booth.", + "ar": "تتيح لك خدمة لايف كير الصيدلية الحصول على استشارة من طبيبك المتواجد فعليًا في كشك صيدلية د.سليمان الحبيب." + }, "wherePharmaLiveCare": {"en": "Where can i find Pharma LiveCare?", "ar": "أين يمكنني أن أجد لايف كير الصيدلية؟"}, "pharmaLiveCareDesc2": {"en": "You can find the booth in HMG Pharmacies.", "ar": "يمكنك العثور على الكشك في صيدليات مستشفى د.سليمان الحبيب."}, "howPharmaLiveCare": {"en": "How can i use Pharma LiveCare?", "ar": "كيف يمكنني استخدام لايف كير الصيدلية؟"}, - "pharmaLiveCareDesc3": {"en": "Following the below steps you can easily benefit from the virtual consultation service:", "ar": "باتباع الخطوات التالية يمكنك الاستفادة بسهولة من خدمة الاستشارة الافتراضية:"}, + "pharmaLiveCareDesc3": { + "en": "Following the below steps you can easily benefit from the virtual consultation service:", + "ar": "باتباع الخطوات التالية يمكنك الاستفادة بسهولة من خدمة الاستشارة الافتراضية:" + }, "pharmaLiveCareScanQR": {"en": "Scan QR Code", "ar": "مسح رمز الاستجابة السريعة"}, "pharmaLiveCareScanQR1": {"en": "Scan the QR Code in the booth to make the connection", "ar": "امسح رمز الاستجابة السريعة في المقصورة لإجراء الاتصال"}, "pharmaLiveCareMakePayment": {"en": "Make Payment Online", "ar": "قم بالدفع عبر الإنترنت"}, @@ -1898,4 +1910,16 @@ const Map localizedValues = { "birthNotificationSubTitle": {"en": "Notification", "ar": "تبليغ الولادة"}, "admissionNoticeTitle": {"en": "Admission", "ar": "إشعار"}, "admissionNoticeSubTitle": {"en": "Notice", "ar": "تنويم"}, -}; \ No newline at end of file + "mothersMRN": {"en": "Mother's MRN", "ar": "رقم ملف الأم"}, + "mothersName": {"en": "Mother's Name", "ar": "اسم الأم"}, + "fathersName": {"en": "Father's Name", "ar": "اسم الاب"}, + "babysName": {"en": "Baby's Name", "ar": "اسم المولود"}, + "contactNumber": {"en": "Contact Number", "ar": "رقم الاتصال"}, + "scanID": {"en": "Scan ID", "ar": "معرف المسح"}, + "birthNotificationNotes1": { + "en": "For Saudis: Provide copy of the identification card for both couples. If the wife doesn't have identification card, The family card must be provided.", + "ar": "للسعوديين : إرفاق صورة من بطاقة الأحوال لكلا الزوجين وفي حال عدم توفر بطاقة الزوجة ترفق عنها بطاقة العائلة" + }, + "birthNotificationNotes2": {"en": "Non Saudis: Provide copy of iqama or copy of the passport.", "ar": ".لغير السعوديين : إرفاق صورة الإقامة آأو جواز السفر"}, + "birthNotificationNotes3": {"en": "For Residents without identification card: Provide marriage contract", "ar": "للمواطنين الغير حاملين لبطاقة الأحوال : إرفاق صورة من عقد الزواج برقم الحاسب"}, +}; diff --git a/lib/pages/InPatientServices/birth_notification.dart b/lib/pages/InPatientServices/birth_notification.dart new file mode 100644 index 00000000..4125261a --- /dev/null +++ b/lib/pages/InPatientServices/birth_notification.dart @@ -0,0 +1,273 @@ +import 'dart:convert'; + +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/insurance/AttachInsuranceCardImageDialog.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class BirthNotification extends StatefulWidget { + const BirthNotification({Key key}) : super(key: key); + + @override + State createState() => _BirthNotificationState(); +} + +class _BirthNotificationState extends State { + TextEditingController motherMRN = new TextEditingController(); + TextEditingController motherName = new TextEditingController(); + TextEditingController fatherName = new TextEditingController(); + TextEditingController babyName = new TextEditingController(); + TextEditingController contactNumber = new TextEditingController(); + + ProjectViewModel projectViewModel; + + List images = []; + + @override + Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + motherMRN.text = projectViewModel.user.patientID.toString(); + motherName.text = projectViewModel.user.firstName + " " + projectViewModel.user.lastName; + contactNumber.text = projectViewModel.user.mobileNumber; + return AppScaffold( + isShowAppBar: true, + isShowDecPage: false, + showNewAppBarTitle: true, + showNewAppBar: true, + appBarTitle: TranslationBase.of(context).birthNotificationTitle + " " + TranslationBase.of(context).birthNotificationSubTitle, + body: SingleChildScrollView( + child: Container( + width: MediaQuery.of(context).size.width, + decoration: containerRadius(Colors.white, 12), + margin: EdgeInsets.all(21.0), + padding: const EdgeInsets.all(21.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).enterDetailBelow + " :", + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + mHeight(16), + inputWidget(TranslationBase.of(context).mothersMRN, "", motherMRN, isEnable: false), + mHeight(16), + inputWidget(TranslationBase.of(context).mothersName, "", motherName, isEnable: false), + mHeight(16), + inputWidget(TranslationBase.of(context).fathersName, "", fatherName), + mHeight(16), + inputWidget(TranslationBase.of(context).babysName, "", babyName), + mHeight(16), + inputWidget(TranslationBase.of(context).contactNumber, "", contactNumber), + mHeight(16), + DefaultButton( + TranslationBase.of(context).scanID, + () { + confirmAttachInsuranceCardImageDialogDialog( + context: context, name: projectViewModel.user.firstName + " " + projectViewModel.user.lastName, fileNo: projectViewModel.user.patientID.toString()); + }, + color: CustomColors.accentColor, + disabledColor: CustomColors.grey2, + ), + if (images.isNotEmpty) mHeight(16), + if (images.isNotEmpty) + Padding( + padding: const EdgeInsets.only(top: 16.0, bottom: 16.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Image.memory( + base64Decode(images[0]), + width: 80.0, + height: 80.0, + fit: BoxFit.cover, + ), + Text( + "image 1.png", + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + InkWell( + onTap: () { + setState(() { + images.clear(); + }); + }, + child: Icon( + Icons.delete_sharp, + color: Colors.red[300], + ), + ) + ], + ), + ), + mHeight(16), + Text( + "● " + TranslationBase.of(context).birthNotificationNotes1, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + mHeight(16), + Text( + "● " + TranslationBase.of(context).birthNotificationNotes2, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + mHeight(16), + Text( + "● " + TranslationBase.of(context).birthNotificationNotes3, + overflow: TextOverflow.clip, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.64, + ), + ), + mHeight(16.0), + DefaultButton( + TranslationBase.of(context).submit, + () {}, + color: CustomColors.accentColor, + disabledColor: CustomColors.grey2, + ), + ], + ), + ), + ), + ); + } + + void confirmAttachInsuranceCardImageDialogDialog({BuildContext context, String name, String fileNo}) { + showDialog( + context: context, + builder: (cxt) => AttachInsuranceCardImageDialog( + fileNo: fileNo, + name: name, + image: (file, image) async { + images.clear(); + images.add(image); + setState(() {}); + // GifLoaderDialogUtils.showMyDialog(context); + // await model.uploadInsuranceCard(context, patientIdentificationID: patientIdentificationID, patientID: patientID, image: image); + // GifLoaderDialogUtils.hideDialog(context); + // if (model.state == ViewState.ErrorLocal || model.state == ViewState.Error) { + // AppToast.showErrorToast(message: model.error); + // } else { + // AppToast.showSuccessToast(message: TranslationBase.of(context).requestSent); + // } + // Navigator.pop(context); + }, + isBirthNotification: true, + ), + ); + } + + Widget inputWidget(String _labelText, String _hintText, TextEditingController _controller, {String prefix, bool isEnable = true, bool hasSelection = false}) { + return Container( + padding: EdgeInsets.only(left: 16, right: 16, bottom: 15, top: 15), + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: Colors.white, + border: Border.all( + color: Color(0xffefefef), + width: 1, + ), + ), + child: InkWell( + onTap: hasSelection ? () {} : null, + child: Row( + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + _labelText, + style: TextStyle( + fontSize: 11, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), + ), + TextField( + enabled: isEnable, + scrollPadding: EdgeInsets.zero, + keyboardType: TextInputType.name, + controller: _controller, + onChanged: (value) => {}, + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), + decoration: InputDecoration( + isDense: true, + hintText: _hintText, + hintStyle: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w400, + color: Color(0xff575757), + letterSpacing: -0.56, + ), + prefixIconConstraints: BoxConstraints(minWidth: 50), + prefixIcon: prefix == null + ? null + : Text( + "+" + prefix, + style: TextStyle( + fontSize: 14, + height: 21 / 14, + fontWeight: FontWeight.w500, + color: Color(0xff2E303A), + letterSpacing: -0.56, + ), + ), + contentPadding: EdgeInsets.zero, + border: InputBorder.none, + focusedBorder: InputBorder.none, + enabledBorder: InputBorder.none, + ), + ), + ], + ), + ), + if (hasSelection) Icon(Icons.keyboard_arrow_down_outlined), + ], + ), + ), + ); + } +} diff --git a/lib/pages/InPatientServices/inpatient_home.dart b/lib/pages/InPatientServices/inpatient_home.dart index 3e82e872..eeba37ab 100644 --- a/lib/pages/InPatientServices/inpatient_home.dart +++ b/lib/pages/InPatientServices/inpatient_home.dart @@ -1,5 +1,6 @@ import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/InPatientServices/get_general_instructions_response_model.dart'; +import 'package:diplomaticquarterapp/pages/InPatientServices/birth_notification.dart'; import 'package:diplomaticquarterapp/pages/InPatientServices/general_instructions.dart'; import 'package:diplomaticquarterapp/pages/InPatientServices/help_PRO.dart'; import 'package:diplomaticquarterapp/pages/InPatientServices/inpatient_advance_payment.dart'; @@ -121,7 +122,7 @@ class InPatientServicesHome extends StatelessWidget { serviceList.add( InkWell( onTap: () { - // Navigator.push(context, FadePage(page: AdvancePaymentPage())); + Navigator.push(context, FadePage(page: BirthNotification())); }, child: MedicalProfileItem( title: TranslationBase.of(context).birthNotificationTitle, diff --git a/lib/pages/insurance/AttachInsuranceCardImageDialog.dart b/lib/pages/insurance/AttachInsuranceCardImageDialog.dart index e7d57363..e0936c30 100644 --- a/lib/pages/insurance/AttachInsuranceCardImageDialog.dart +++ b/lib/pages/insurance/AttachInsuranceCardImageDialog.dart @@ -14,8 +14,9 @@ class AttachInsuranceCardImageDialog extends StatefulWidget { final String name; final String fileNo; final Function(File file, String image) image; + final bool isBirthNotification; - const AttachInsuranceCardImageDialog({Key key, this.name, this.fileNo, this.image}) : super(key: key); + const AttachInsuranceCardImageDialog({Key key, this.name, this.fileNo, this.image, this.isBirthNotification = false}) : super(key: key); @override _AttachInsuranceCardImageDialogState createState() => _AttachInsuranceCardImageDialogState(); @@ -38,7 +39,7 @@ class _AttachInsuranceCardImageDialogState extends State localizedValues["birthNotificationSubTitle"][locale.languageCode]; String get admissionNoticeTitle => localizedValues["admissionNoticeTitle"][locale.languageCode]; String get admissionNoticeSubTitle => localizedValues["admissionNoticeSubTitle"][locale.languageCode]; + String get mothersMRN => localizedValues["mothersMRN"][locale.languageCode]; + String get mothersName => localizedValues["mothersName"][locale.languageCode]; + String get fathersName => localizedValues["fathersName"][locale.languageCode]; + String get babysName => localizedValues["babysName"][locale.languageCode]; + String get contactNumber => localizedValues["contactNumber"][locale.languageCode]; + String get scanID => localizedValues["scanID"][locale.languageCode]; + String get birthNotificationNotes1 => localizedValues["birthNotificationNotes1"][locale.languageCode]; + String get birthNotificationNotes2 => localizedValues["birthNotificationNotes2"][locale.languageCode]; + String get birthNotificationNotes3 => localizedValues["birthNotificationNotes3"][locale.languageCode]; } diff --git a/lib/widgets/bottom_options/BottomSheet.dart b/lib/widgets/bottom_options/BottomSheet.dart index 5399a4c3..72349e82 100644 --- a/lib/widgets/bottom_options/BottomSheet.dart +++ b/lib/widgets/bottom_options/BottomSheet.dart @@ -70,7 +70,7 @@ class ImageOptions { } galleryImageAndroid(Function(String, File) image) async { - if(await PermissionService.isExternalStorageEnabled()) { + if (await PermissionService.isExternalStorageEnabled()) { File _image = File((await ImagePicker.platform.pickImage(source: ImageSource.gallery, imageQuality: 20)).path); String fileName = _image.path; final bytes = File(fileName).readAsBytesSync();