diff --git a/lib/config/config.dart b/lib/config/config.dart index 57c257b0..232209f8 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -49,6 +49,7 @@ const WIFI_CREDENTIALS = const GET_MY_DOCTOR = 'Services/Doctors.svc/REST/GetPatientDoctorAppointmentResult'; const GET_DOCTOR_PROFILE = 'Services/Doctors.svc/REST/GetDocProfiles'; +const GET_DOCTOR_PRE_POST_IMAGES = 'Services/Doctors.svc/REST/GetDoctorPrePostImages'; const GET_DOCTOR_RATING_NOTES = 'Services/Doctors.svc/REST/dr_GetNotesDoctorRating'; const GET_DOCTOR_RATING_DETAILS = diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index e45af168..5cf126ef 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -59,6 +59,7 @@ const Map localizedValues = { 'logout': {'en': 'Logout', 'ar': 'تسجيل خروج'}, 'respirationRate': {'en': 'Respiration Rate', 'ar': 'معدل التنفس'}, 'bookAppo': {'en': 'Book Appointment', 'ar': 'حجز موعد'}, + 'beforeAfterImages': {'en': 'Before After Images', 'ar': 'قبل بعد الصور'}, 'searchBy': {'en': 'Search By:', 'ar': 'البحث عن طريق:'}, 'clinic': {'en': 'Clinic', 'ar': 'العيادة'}, 'hospital': {'en': 'Hospital', 'ar': 'المستشفى'}, diff --git a/lib/models/Appointments/DoctorListResponse.dart b/lib/models/Appointments/DoctorListResponse.dart index 4c7241c8..a038aaf4 100644 --- a/lib/models/Appointments/DoctorListResponse.dart +++ b/lib/models/Appointments/DoctorListResponse.dart @@ -21,6 +21,7 @@ class DoctorList { bool isDoctorAllowVedioCall; bool isDoctorDummy; bool isLiveCare; + bool isDoctorHasPrePostImages; String latitude; String longitude; String nationalityFlagURL; @@ -62,6 +63,7 @@ class DoctorList { this.isDoctorAllowVedioCall, this.isDoctorDummy, this.isLiveCare, + this.isDoctorHasPrePostImages, this.latitude, this.longitude, this.nationalityFlagURL, @@ -103,6 +105,7 @@ class DoctorList { isDoctorAllowVedioCall = json['IsDoctorAllowVedioCall']; isDoctorDummy = json['IsDoctorDummy']; isLiveCare = json['IsLiveCare']; + isDoctorHasPrePostImages = json['IsDoctorHasPrePostImages']; latitude = json['Latitude']; longitude = json['Longitude']; nationalityFlagURL = json['NationalityFlagURL']; @@ -147,6 +150,7 @@ class DoctorList { data['IsDoctorAllowVedioCall'] = this.isDoctorAllowVedioCall; data['IsDoctorDummy'] = this.isDoctorDummy; data['IsLiveCare'] = this.isLiveCare; + data['IsDoctorHasPrePostImages'] = this.isDoctorHasPrePostImages; data['Latitude'] = this.latitude; data['Longitude'] = this.longitude; data['NationalityFlagURL'] = this.nationalityFlagURL; diff --git a/lib/models/Appointments/DoctorProfile.dart b/lib/models/Appointments/DoctorProfile.dart index bfc8c189..9b2bc8e9 100644 --- a/lib/models/Appointments/DoctorProfile.dart +++ b/lib/models/Appointments/DoctorProfile.dart @@ -24,6 +24,7 @@ class DoctorProfileList { Null isRegistered; Null isDoctorDummy; bool isActive; + bool isDoctorHasPrePostImages; Null isDoctorAppointmentDisplayed; bool doctorClinicActive; Null isbookingAllowed; @@ -67,6 +68,7 @@ class DoctorProfileList { this.isRegistered, this.isDoctorDummy, this.isActive, + this.isDoctorHasPrePostImages, this.isDoctorAppointmentDisplayed, this.doctorClinicActive, this.isbookingAllowed, @@ -110,6 +112,7 @@ class DoctorProfileList { isRegistered = json['IsRegistered']; isDoctorDummy = json['IsDoctorDummy']; isActive = json['IsActive']; + isDoctorHasPrePostImages = json['IsDoctorHasPrePostImages']; isDoctorAppointmentDisplayed = json['IsDoctorAppointmentDisplayed']; doctorClinicActive = json['DoctorClinicActive']; isbookingAllowed = json['IsbookingAllowed']; @@ -155,6 +158,7 @@ class DoctorProfileList { data['IsRegistered'] = this.isRegistered; data['IsDoctorDummy'] = this.isDoctorDummy; data['IsActive'] = this.isActive; + data['IsDoctorHasPrePostImages'] = this.isDoctorHasPrePostImages; data['IsDoctorAppointmentDisplayed'] = this.isDoctorAppointmentDisplayed; data['DoctorClinicActive'] = this.doctorClinicActive; data['IsbookingAllowed'] = this.isbookingAllowed; diff --git a/lib/models/Appointments/doctor_pre_post_image.dart b/lib/models/Appointments/doctor_pre_post_image.dart new file mode 100644 index 00000000..cb68a472 --- /dev/null +++ b/lib/models/Appointments/doctor_pre_post_image.dart @@ -0,0 +1,107 @@ +import 'dart:convert'; +import 'dart:typed_data'; + +import 'package:diplomaticquarterapp/uitl/utils.dart'; + +class DoctorPrePostImages { + DoctorPrePostImageModel pre; + DoctorPrePostImageModel post; + + Uint8List getPreBytes(){ + try{ + var b64 = pre.imageStr.replaceFirst('data:image/png;base64,', ''); + if(pre.imageStr != null && isBase64(b64)) + return Utils.dataFromBase64String(b64); + }catch(e){ + + } + return null; + } + + Uint8List getPostBytes(){ + try{ + var b64 = post.imageStr.replaceFirst('data:image/png;base64,', ''); + if(post.imageStr != null && isBase64(b64)) + return Utils.dataFromBase64String(b64); + }catch(e){ + + } + return null; + } + + bool isBase64(String str) { + RegExp _base64 = RegExp( + r'^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{4})$'); + return _base64.hasMatch(str); + } +} + +class DoctorPrePostImageModel { + String setupID; + int projectID; + int clinicId; + int doctorId; + int lineItemNo; + String imageStr; + int imageType; + String description; + dynamic isNewUpdated; + bool isActive; + String createdOn; + int createdBy; + dynamic editedOn; + dynamic editedBy; + + DoctorPrePostImageModel({ + this.setupID, + this.projectID, + this.clinicId, + this.doctorId, + this.lineItemNo, + this.imageStr, + this.imageType, + this.description, + this.isNewUpdated, + this.isActive, + this.createdOn, + this.createdBy, + this.editedOn, + this.editedBy}); + + DoctorPrePostImageModel.fromJson(dynamic json) { + setupID = json["SetupID"]; + projectID = json["ProjectID"]; + clinicId = json["ClinicId"]; + doctorId = json["DoctorId"]; + lineItemNo = json["LineItemNo"]; + imageStr = json["ImageStr"]; + imageType = json["ImageType"]; + description = json["Description"]; + isNewUpdated = json["IsNewUpdated"]; + isActive = json["IsActive"]; + createdOn = json["CreatedOn"]; + createdBy = json["CreatedBy"]; + editedOn = json["EditedOn"]; + editedBy = json["EditedBy"]; + } + + Map toJson() { + var map = {}; + map["SetupID"] = setupID; + map["ProjectID"] = projectID; + map["ClinicId"] = clinicId; + map["DoctorId"] = doctorId; + map["LineItemNo"] = lineItemNo; + map["ImageStr"] = imageStr; + map["ImageType"] = imageType; + map["Description"] = description; + map["IsNewUpdated"] = isNewUpdated; + map["IsActive"] = isActive; + map["CreatedOn"] = createdOn; + map["CreatedBy"] = createdBy; + map["EditedOn"] = editedOn; + map["EditedBy"] = editedBy; + return map; + } + +} \ No newline at end of file diff --git a/lib/pages/BookAppointment/DoctorProfile.dart b/lib/pages/BookAppointment/DoctorProfile.dart index fd89889f..949f2c44 100644 --- a/lib/pages/BookAppointment/DoctorProfile.dart +++ b/lib/pages/BookAppointment/DoctorProfile.dart @@ -3,6 +3,7 @@ import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart import 'package:diplomaticquarterapp/models/Appointments/DoctorProfile.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorRateDetails.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/doctor_post_pre_images_page.dart'; import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; import 'package:diplomaticquarterapp/services/robo_search/event_provider.dart'; @@ -14,6 +15,7 @@ import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_material_pickers/flutter_material_pickers.dart'; import 'package:rating_bar/rating_bar.dart'; import 'BookConfirm.dart'; @@ -176,8 +178,15 @@ class _DoctorProfileState extends State )), ), ), + + if(widget.docProfileList.isDoctorHasPrePostImages == true) + Container( + height: 50, + alignment: Alignment.center, + child: prePostImagesButton(context) + ), + Container( - margin: EdgeInsets.only(top: 10.0), child: Divider( color: Colors.grey[500], ), @@ -225,6 +234,19 @@ class _DoctorProfileState extends State ); } + Widget prePostImagesButton(BuildContext context){ + return Padding( + padding: const EdgeInsets.all(10), + child: MaterialButton( + height: 50, + color: Theme.of(context).appBarTheme.color, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), + onPressed: () => openDoctorPrePostImages(), + child: Text(TranslationBase.of(context).beforeAfterImages, style: TextStyle(color: Colors.white, fontSize: 15, letterSpacing: 1),), + ), + ); + } + getDoctorRatings() { GifLoaderDialogUtils.showMyDialog(context); DoctorsListService service = new DoctorsListService(); @@ -265,6 +287,30 @@ class _DoctorProfileState extends State }); } + openDoctorPrePostImages(){ + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService().getDoctorPrePostImages(widget.docProfileList, context).then((images) { + GifLoaderDialogUtils.hideDialog(context); + showDialog( + context: context, barrierDismissible: true, + builder: (ctx){ + return DoctorPostPreImagesContent(doctorPrePostImages: images); + } + ); + // Navigator.push( + // context, + // FadePage( + // page: DoctorPostPreImagesPage(doctorPrePostImages: images,) + // ) + // ); + + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + void showRatingDialog(List doctorDetailsList) { showGeneralDialog( barrierColor: Colors.black.withOpacity(0.5), @@ -566,4 +612,6 @@ class _DoctorProfileState extends State selectedDate: DocAvailableAppointments.selectedDate, selectedTime: DocAvailableAppointments.selectedTime))); } + + } diff --git a/lib/pages/BookAppointment/doctor_post_pre_images_page.dart b/lib/pages/BookAppointment/doctor_post_pre_images_page.dart new file mode 100644 index 00000000..b97d58ac --- /dev/null +++ b/lib/pages/BookAppointment/doctor_post_pre_images_page.dart @@ -0,0 +1,121 @@ +import 'package:diplomaticquarterapp/models/Appointments/DoctorProfile.dart'; +import 'package:diplomaticquarterapp/models/Appointments/doctor_pre_post_image.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class DoctorPostPreImagesPage extends StatefulWidget{ + final DoctorPrePostImages doctorPrePostImages; + + const DoctorPostPreImagesPage({this.doctorPrePostImages}); + + @override + State createState() => DoctorPostPreImagesPageState(); +} + +class DoctorPostPreImagesPageState extends State{ + + @override + Widget build(BuildContext context) { + var images = widget.doctorPrePostImages; + return AppScaffold( + appBarTitle: TranslationBase.of(context).beforeAfterImages, + isShowAppBar: true, + isShowDecPage: false, + body: Padding( + padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 10), + child: Row( + children: [ + Expanded( + child: Column( + children: [ + Text("Before Image", style: TextStyle(color: Colors.black, fontSize: 17, fontWeight: FontWeight.bold, letterSpacing: 1),), + Image.memory(images.getPreBytes(), errorBuilder: (ctx,err, trace){ + return Container( + color: Colors.grey.withOpacity(0.25), + ); + },) + ], + ) + ), + Divider(color: Colors.grey.withOpacity(0.5)), + Expanded( + child: Column( + children: [ + Text("After Image", style: TextStyle(color: Colors.black, fontSize: 17, fontWeight: FontWeight.bold, letterSpacing: 1),), + Image.memory(images.getPostBytes(),errorBuilder: (ctx,err, trace){ + return Container( + color: Colors.grey.withOpacity(0.25), + ); + },) + ], + ) + ) + ], + ), + ) + ); + } + +} + + +class DoctorPostPreImagesContent extends StatefulWidget{ + final DoctorPrePostImages doctorPrePostImages; + + const DoctorPostPreImagesContent({this.doctorPrePostImages}); + + @override + DoctorPostPreImagesContentState createState() => DoctorPostPreImagesContentState(); +} + +class DoctorPostPreImagesContentState extends State{ + + @override + Widget build(BuildContext context) { + var images = widget.doctorPrePostImages; + return Material( + color: Colors.transparent, + child: Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + children: [ + Expanded( + child: Column( + children: [ + Text("Before", style: TextStyle(color: Colors.white, fontSize: 17, fontWeight: FontWeight.bold, letterSpacing: 1),), + SizedBox(height: 10,), + Image.memory(images.getPreBytes(), errorBuilder: (ctx,err, trace){ + return Container( + color: Colors.grey.withOpacity(0.25), + ); + },) + ], + ) + ), + Divider(color: Colors.grey.withOpacity(0.5)), + Expanded( + child: Column( + children: [ + Text("After", style: TextStyle(color: Colors.white, fontSize: 17, fontWeight: FontWeight.bold, letterSpacing: 1),), + SizedBox(height: 10,), + Image.memory(images.getPostBytes(),errorBuilder: (ctx,err, trace){ + return Container( + color: Colors.grey.withOpacity(0.25), + ); + },) + ], + ) + ) + ], + ), + ], + ), + ), + ); + } + +} \ No newline at end of file diff --git a/lib/pages/login/login.dart b/lib/pages/login/login.dart index 1c0fd13e..c5da90d5 100644 --- a/lib/pages/login/login.dart +++ b/lib/pages/login/login.dart @@ -64,6 +64,11 @@ class _Login extends State { void initState() { // getDeviceToken(); super.initState(); + + if(BASE_URL.contains("uat.")){ + nationalIDorFile.text = "1231755"; + mobileNumberController.text = mobileNo = "537503378"; + } } getDeviceToken() async { diff --git a/lib/services/appointment_services/GetDoctorsList.dart b/lib/services/appointment_services/GetDoctorsList.dart index fb55d538..b97714ce 100644 --- a/lib/services/appointment_services/GetDoctorsList.dart +++ b/lib/services/appointment_services/GetDoctorsList.dart @@ -4,7 +4,9 @@ import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorProfile.dart'; import 'package:diplomaticquarterapp/models/Appointments/PatientShareResposne.dart'; +import 'package:diplomaticquarterapp/models/Appointments/doctor_pre_post_image.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/models/Request.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; @@ -157,7 +159,7 @@ class DoctorsListService extends BaseService { "VersionID": req.VersionID, "Channel": req.Channel, "generalid": 'Cs2020@2016\$2958', - "PatientOutSA": authUser.outSA, + "PatientOutSA": authUser.outSA ?? false, "TokenID": "", "DeviceTypeID": req.DeviceTypeID, "SessionID": null, @@ -184,7 +186,7 @@ class DoctorsListService extends BaseService { Future getDoctorsRating(int docID, context) async { Map request; var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { "LanguageID": languageID == 'ar' ? 1 : 2, @@ -207,13 +209,40 @@ class DoctorsListService extends BaseService { await baseAppClient.post(GET_DOCTOR_RATING_NOTES, onSuccess: (response, statusCode) async { - localRes = response; - }, onFailure: (String error, int statusCode) { - throw error; - }, body: request); + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); return Future.value(localRes); } + Future getDoctorPrePostImages(DoctorProfileList doctorProfile, context) async { + Map request; + request = { + "PatientOutSA": authUser.outSA ?? 0, + "isDentalAllowedBackend": false, + "DoctorID" : doctorProfile.doctorID, + "ClinicID":doctorProfile.clinicID, + "ProjectID":doctorProfile.projectID + }; + + var images = DoctorPrePostImages(); + await baseAppClient.post(GET_DOCTOR_PRE_POST_IMAGES, + onSuccess: (response, statusCode) async { + var list = response['DoctorPrePostImagesList']; + if (list is List && list.length > 0){ + list.forEach((j) { + var image = DoctorPrePostImageModel.fromJson(j); + if(image.imageType == 1) images.pre = image; + if(image.imageType == 2) images.post = image; + }); + } + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(images); + } + Future getDoctorsRatingDetails(int docID, context) async { Map request; var languageID = diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index 795e9228..9ea40910 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -45,6 +45,8 @@ class TranslationBase { String get bookAppo => localizedValues['bookAppo'][locale.languageCode]; + String get beforeAfterImages => localizedValues['beforeAfterImages'][locale.languageCode]; + String get searchBy => localizedValues['searchBy'][locale.languageCode]; String get clinic => localizedValues['clinic'][locale.languageCode];