diff --git a/lib/core/api_consts.dart b/lib/core/api_consts.dart index 5886dfa..9b013a5 100644 --- a/lib/core/api_consts.dart +++ b/lib/core/api_consts.dart @@ -808,6 +808,9 @@ class ApiConsts { static final String registerUser = 'Services/Authentication.svc/REST/PatientRegistration'; static final String addFamilyFile = 'Services/Patients.svc/REST/ShareFamilyFileService'; + static final String sendFamilyFileActivation = 'Services/Authentication.svc/REST/SendActivationCodeForFamilyFile'; + static final String checkActivationCodeForFamily = 'Services/Authentication.svc/REST/CheckActivationCodeForFamilyFile'; + // static values for Api static final double appVersionID = 18.7; diff --git a/lib/core/utils/request_utils.dart b/lib/core/utils/request_utils.dart index 8b993f1..cd813ed 100644 --- a/lib/core/utils/request_utils.dart +++ b/lib/core/utils/request_utils.dart @@ -9,6 +9,7 @@ import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/features/authentication/models/request_models/registration_payload_model.dart'; import 'package:hmg_patient_app_new/features/authentication/models/request_models/send_activation_request_model.dart'; import 'package:hmg_patient_app_new/features/common/models/commong_authanticated_req_model.dart'; +import 'package:hmg_patient_app_new/features/common/models/family_file_request.dart'; class RequestUtils { static dynamic getPatientAuthenticationRequest({ @@ -125,6 +126,9 @@ class RequestUtils { required bool isForRegister, required bool isFileNo, dynamic payload, + required bool isExcludedUser, + required bool isFormFamilyFile, + int? responseID, }) { AppState _appState = getIt.get(); var request = SendActivationRequest(); @@ -156,6 +160,15 @@ class RequestUtils { request.isRegister = false; } request.deviceTypeID = request.searchType; + + if (isFormFamilyFile) { + //INFO: Only for Excluded User Family Member Addition + request.isPatientExcluded = isExcludedUser; + request.responseID = responseID; + request.status = 2; + request.familyRegionID = zipCode == CountryEnum.saudiArabia.countryCode ? 1 : 2; + } + return request; } @@ -247,19 +260,29 @@ class RequestUtils { }; } - static dynamic getAddFamilyRequest({required String nationalIDorFile, required String mobileNo, required String countryCode, required int loginType}) { - var request = {}; + static Future getAddFamilyRequest({required String nationalIDorFile, required String mobileNo, required String countryCode}) async { + FamilyFileRequest request = FamilyFileRequest(); + int? loginType = 0; // Default to National ID + + if (countryCode == CountryEnum.saudiArabia.countryCode || countryCode == '+966') { + loginType = (nationalIDorFile.length == 10) ? 1 : 2; + } else if (countryCode == CountryEnum.unitedArabEmirates.countryCode || countryCode == '+971') { + loginType = (nationalIDorFile.length == 15) ? 1 : 2; + } + if (loginType == 1) { - request["sharedPatientID"] = 0; - request["sharedPatientIdentificationID"] = nationalIDorFile; + request.sharedPatientId = 0; + request.sharedPatientIdentificationId = nationalIDorFile; } else if (loginType == 2) { - request["sharedPatientID"] = int.parse(nationalIDorFile); - request["sharedPatientIdentificationID"] = ''; + request.sharedPatientId = int.parse(nationalIDorFile); + request.sharedPatientIdentificationId = ''; } - request["searchType"] = loginType; - request["sharedPatientMobileNumber"] = mobileNo; - request["zipCode"] = countryCode; - request["isRegister"] = false; - request["patientStatus"] = 2; + request.searchType = loginType; + request.sharedPatientMobileNumber = mobileNo; + request.zipCode = countryCode; + request.isRegister = false; + request.patientStatus = 2; + request.isDentalAllowedBackend = false; + return request; } } diff --git a/lib/features/authentication/authentication_repo.dart b/lib/features/authentication/authentication_repo.dart index 2eaeb80..8038c43 100644 --- a/lib/features/authentication/authentication_repo.dart +++ b/lib/features/authentication/authentication_repo.dart @@ -17,12 +17,9 @@ abstract class AuthenticationRepo { Future>> checkPatientAuthentication({required dynamic checkPatientAuthenticationReq}); - Future>> sendActivationCodeRepo({required dynamic sendActivationCodeReq, String? languageID, bool isRegister = false}); + Future>> sendActivationCodeRepo({required dynamic sendActivationCodeReq, String? languageID, bool isRegister = false, bool isFormFamilyFile = false}); - Future>> checkActivationCodeRepo( - {required dynamic newRequest, // could be CheckActivationCodeReq or CheckActivationCodeRegisterReq - required String? activationCode, - required bool isRegister}); + Future>> checkActivationCodeRepo({required dynamic newRequest, required String? activationCode, required bool isRegister, bool isExcludedUser = false}); Future>> checkIfUserAgreed({required dynamic commonAuthanticatedRequest}); @@ -134,6 +131,7 @@ class AuthenticationRepoImp implements AuthenticationRepo { required dynamic sendActivationCodeReq, String? languageID, bool isRegister = false, + bool isFormFamilyFile = false, }) async { int isOutKsa = (sendActivationCodeReq.zipCode == '966' || sendActivationCodeReq.zipCode == '+966') ? 0 : 1; sendActivationCodeReq.patientOutSA = isOutKsa; @@ -144,7 +142,11 @@ class AuthenticationRepoImp implements AuthenticationRepo { Failure? failure; await apiClient.post( - isRegister ? ApiConsts.sendActivationCodeRegister : ApiConsts.sendActivationCode, + isFormFamilyFile + ? ApiConsts.sendFamilyFileActivation + : isRegister + ? ApiConsts.sendActivationCodeRegister + : ApiConsts.sendActivationCode, body: sendActivationCodeReq.toJson(), onFailure: (error, statusCode, {messageStatus, failureType}) { failure = failureType; @@ -176,6 +178,7 @@ class AuthenticationRepoImp implements AuthenticationRepo { required dynamic newRequest, // could be CheckActivationCodeReq or CheckActivationCodeRegisterReq required String? activationCode, required bool isRegister, + bool isExcludedUser = false, }) async { if (isRegister) { newRequest["activationCode"] = activationCode ?? "0000"; @@ -189,7 +192,11 @@ class AuthenticationRepoImp implements AuthenticationRepo { newRequest.isRegister = false; } - final endpoint = isRegister ? ApiConsts.checkActivationCodeRegister : ApiConsts.checkActivationCode; + final endpoint = isExcludedUser + ? ApiConsts.checkActivationCodeForFamily + : isRegister + ? ApiConsts.checkActivationCodeRegister + : ApiConsts.checkActivationCode; try { GenericApiModel? apiResponse; diff --git a/lib/features/authentication/authentication_view_model.dart b/lib/features/authentication/authentication_view_model.dart index c8adf78..558f02d 100644 --- a/lib/features/authentication/authentication_view_model.dart +++ b/lib/features/authentication/authentication_view_model.dart @@ -13,6 +13,7 @@ import 'package:hmg_patient_app_new/core/common_models/privilege/HMCProjectListM import 'package:hmg_patient_app_new/core/common_models/privilege/PrivilegeModel.dart'; import 'package:hmg_patient_app_new/core/common_models/privilege/ProjectDetailListModel.dart'; import 'package:hmg_patient_app_new/core/common_models/privilege/VidaPlusProjectListModel.dart'; +import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/enums.dart'; import 'package:hmg_patient_app_new/core/utils/loading_utils.dart'; import 'package:hmg_patient_app_new/core/utils/request_utils.dart'; @@ -27,6 +28,7 @@ import 'package:hmg_patient_app_new/features/authentication/models/resp_models/a import 'package:hmg_patient_app_new/features/authentication/models/resp_models/check_activation_code_resp_model.dart'; import 'package:hmg_patient_app_new/features/authentication/models/resp_models/check_user_staus_nhic_response_model.dart'; import 'package:hmg_patient_app_new/features/authentication/models/resp_models/select_device_by_imei.dart'; +import 'package:hmg_patient_app_new/features/medical_file/medical_file_repo.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/authentication/login.dart'; import 'package:hmg_patient_app_new/presentation/authentication/saved_login_screen.dart'; @@ -345,23 +347,33 @@ class AuthenticationViewModel extends ChangeNotifier { } Future sendActivationCode( - {required OTPTypeEnum otpTypeEnum, required String nationalIdOrFileNumber, required String phoneNumber, required bool isForRegister, dynamic payload, bool isComingFromResendOTP = false}) async { + {required OTPTypeEnum otpTypeEnum, + required String nationalIdOrFileNumber, + required String phoneNumber, + required bool isForRegister, + dynamic payload, + bool isComingFromResendOTP = false, + bool isExcludedUser = false, + bool isFormFamilyFile = false, + int? responseID}) async { var request = RequestUtils.getCommonRequestSendActivationCode( - otpTypeEnum: otpTypeEnum, - mobileNumber: phoneNumber, - selectedLoginType: otpTypeEnum.toInt(), - zipCode: selectedCountrySignup.countryCode, - nationalId: int.parse(nationalIdOrFileNumber), - isFileNo: isForRegister ? isPatientHasFile(request: payload) : false, - patientId: 0, - isForRegister: isForRegister, - patientOutSA: isForRegister - ? isPatientOutsideSA(request: payload) - : selectedCountrySignup.countryCode == CountryEnum.saudiArabia - ? false - : true, - payload: payload, - ); + otpTypeEnum: otpTypeEnum, + mobileNumber: phoneNumber, + selectedLoginType: otpTypeEnum.toInt(), + zipCode: selectedCountrySignup.countryCode, + nationalId: int.parse(nationalIdOrFileNumber), + isFileNo: isForRegister ? isPatientHasFile(request: payload) : false, + patientId: 0, + isForRegister: isForRegister, + patientOutSA: isForRegister + ? isPatientOutsideSA(request: payload) + : selectedCountrySignup.countryCode == CountryEnum.saudiArabia + ? false + : true, + payload: payload, + isExcludedUser: isExcludedUser, + isFormFamilyFile: isFormFamilyFile, + responseID: responseID); // TODO: GET APP SMS SIGNATURE HERE request.sMSSignature = await getSignature(); @@ -370,7 +382,8 @@ class AuthenticationViewModel extends ChangeNotifier { _appState.setUserRegistrationPayload = RegistrationDataModelPayload.fromJson(payload); } - final resultEither = await _authenticationRepo.sendActivationCodeRepo(sendActivationCodeReq: request, isRegister: checkIsUserComingForRegister(request: payload), languageID: 'er'); + final resultEither = + await _authenticationRepo.sendActivationCodeRepo(sendActivationCodeReq: request, isRegister: checkIsUserComingForRegister(request: payload), languageID: 'er', isFormFamilyFile: isFormFamilyFile); resultEither.fold( (failure) async => await _errorHandlerService.handleError(failure: failure), @@ -385,7 +398,10 @@ class AuthenticationViewModel extends ChangeNotifier { } else { if (apiResponse.data != null && apiResponse.data['isSMSSent'] == true) { LoaderBottomSheet.hideLoader(); - if (!isComingFromResendOTP) navigateToOTPScreen(otpTypeEnum: otpTypeEnum, phoneNumber: phoneNumber, isComingFromRegister: checkIsUserComingForRegister(request: payload), payload: payload); + if (!isComingFromResendOTP) { + navigateToOTPScreen( + otpTypeEnum: otpTypeEnum, phoneNumber: phoneNumber, isComingFromRegister: checkIsUserComingForRegister(request: payload), payload: payload, isExcludedUser: isExcludedUser); + } } else { // TODO: Handle isSMSSent false // navigateToOTPScreen(otpTypeEnum: otpTypeEnum, phoneNumber: phoneNumber); @@ -404,7 +420,13 @@ class AuthenticationViewModel extends ChangeNotifier { } Future checkActivationCode( - {required String? activationCode, required OTPTypeEnum otpTypeEnum, required Function(String? message) onWrongActivationCode, Function()? onResendActivation}) async { + {required String? activationCode, + required OTPTypeEnum otpTypeEnum, + required Function(String? message) onWrongActivationCode, + Function()? onResendActivation, + bool isExcludedUser = false, + dynamic requestID, + dynamic responseID}) async { bool isForRegister = (_appState.getUserRegistrationPayload.healthId != null || _appState.getUserRegistrationPayload.patientOutSa == true || _appState.getUserRegistrationPayload.patientOutSa == 1); final request = RequestUtils.getCommonRequestWelcome( @@ -430,6 +452,13 @@ class AuthenticationViewModel extends ChangeNotifier { //TODO: Error Here IN Zip Code. loginType: loginTypeEnum.toInt) .toJson(); + + if (isExcludedUser) { + request['PatientShareRequestID'] = requestID; + request['ResponseID'] = responseID; + request['Status'] = 3; + } + LoaderBottomSheet.showLoader(); if (isForRegister) { if (_appState.getUserRegistrationPayload.patientOutSa == 0) request['DOB'] = _appState.getUserRegistrationPayload.dob; @@ -465,7 +494,8 @@ class AuthenticationViewModel extends ChangeNotifier { } }); } else { - final resultEither = await _authenticationRepo.checkActivationCodeRepo(newRequest: CheckActivationCodeRegisterReq.fromJson(request), activationCode: activationCode, isRegister: false); + final resultEither = await _authenticationRepo.checkActivationCodeRepo( + newRequest: CheckActivationCodeRegisterReq.fromJson(request), activationCode: activationCode, isRegister: false, isExcludedUser: isExcludedUser); resultEither.fold( (failure) async => await _errorHandlerService.handleError( @@ -575,12 +605,13 @@ class AuthenticationViewModel extends ChangeNotifier { _navigationService.pushAndReplace(AppRoutes.landingScreen); } - Future navigateToOTPScreen({required OTPTypeEnum otpTypeEnum, required String phoneNumber, required bool isComingFromRegister, dynamic payload}) async { + Future navigateToOTPScreen({required OTPTypeEnum otpTypeEnum, required String phoneNumber, required bool isComingFromRegister, dynamic payload, bool isExcludedUser = false}) async { _navigationService.pushToOtpScreen( phoneNumber: phoneNumber, checkActivationCode: (int activationCode) async { await checkActivationCode( activationCode: activationCode.toString(), + isExcludedUser: isExcludedUser, otpTypeEnum: otpTypeEnum, onWrongActivationCode: (String? value) { onWrongActivationCode(message: value); diff --git a/lib/features/common/models/family_file_request.dart b/lib/features/common/models/family_file_request.dart new file mode 100644 index 0000000..047b9af --- /dev/null +++ b/lib/features/common/models/family_file_request.dart @@ -0,0 +1,57 @@ +import 'dart:convert'; + +class FamilyFileRequest { + int? sharedPatientId; + String? sharedPatientIdentificationId; + int? searchType; + String? sharedPatientMobileNumber; + String? zipCode; + bool? isRegister; + int? patientStatus; + bool? isDentalAllowedBackend; + bool? isPatientExcluded; + int? responseID; + + FamilyFileRequest({ + this.sharedPatientId, + this.sharedPatientIdentificationId, + this.searchType, + this.sharedPatientMobileNumber, + this.zipCode, + this.isRegister, + this.patientStatus, + this.isDentalAllowedBackend, + this.isPatientExcluded, + this.responseID, + }); + + factory FamilyFileRequest.fromRawJson(String str) => FamilyFileRequest.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory FamilyFileRequest.fromJson(Map json) => FamilyFileRequest( + sharedPatientId: json["sharedPatientID"], + sharedPatientIdentificationId: json["sharedPatientIdentificationID"], + searchType: json["searchType"], + sharedPatientMobileNumber: json["sharedPatientMobileNumber"], + zipCode: json["zipCode"], + isRegister: json["isRegister"], + patientStatus: json["patientStatus"], + isDentalAllowedBackend: json["isDentalAllowedBackend"], + isPatientExcluded: json["IsPatientExcluded"], + responseID: json["ReponseID"], + ); + + Map toJson() => { + "SharedPatientID": sharedPatientId, + "SharedPatientIdentificationID": sharedPatientIdentificationId, + "SearchType": searchType, + "SharedPatientMobileNumber": sharedPatientMobileNumber, + "zipCode": zipCode, + "isRegister": isRegister, + "PatientStatus": patientStatus, + "isDentalAllowedBackend": isDentalAllowedBackend, + "IsPatientExcluded": isPatientExcluded, + "ReponseID": responseID, + }; +} diff --git a/lib/features/medical_file/medical_file_repo.dart b/lib/features/medical_file/medical_file_repo.dart index 6b83f33..3042aba 100644 --- a/lib/features/medical_file/medical_file_repo.dart +++ b/lib/features/medical_file/medical_file_repo.dart @@ -26,7 +26,7 @@ abstract class MedicalFileRepo { Future>>> getPatientFamilyFiles(); - Future>>> addFamilyFile({required dynamic request}); + Future>> addFamilyFile({required dynamic request}); } class MedicalFileRepoImp implements MedicalFileRepo { @@ -313,9 +313,9 @@ class MedicalFileRepoImp implements MedicalFileRepo { } @override - Future>>> addFamilyFile({dynamic request}) async { + Future>> addFamilyFile({dynamic request}) async { try { - GenericApiModel>? apiResponse; + GenericApiModel? apiResponse; Failure? failure; await apiClient.post( ApiConsts.addFamilyFile, @@ -325,17 +325,12 @@ class MedicalFileRepoImp implements MedicalFileRepo { }, onSuccess: (response, statusCode, {messageStatus, errorMessage}) { try { - print(response); - // final list = response['GetAllSharedRecordsByStatusList']; - // - // final familyLists = list.map((item) => FamilyFileResponseModelLists.fromJson(item as Map)).toList().cast(); - // - // apiResponse = GenericApiModel>( - // messageStatus: messageStatus, - // statusCode: statusCode, - // errorMessage: null, - // data: familyLists, - // ); + apiResponse = GenericApiModel( + messageStatus: messageStatus, + statusCode: statusCode, + errorMessage: errorMessage, + data: response["ShareFamilyFileObj"] ?? null, + ); } catch (e) { failure = DataParsingFailure(e.toString()); } diff --git a/lib/features/medical_file/medical_file_view_model.dart b/lib/features/medical_file/medical_file_view_model.dart index 2e528de..1c3d353 100644 --- a/lib/features/medical_file/medical_file_view_model.dart +++ b/lib/features/medical_file/medical_file_view_model.dart @@ -1,8 +1,14 @@ +import 'dart:convert'; + import 'package:flutter/material.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/enums.dart'; import 'package:hmg_patient_app_new/core/utils/request_utils.dart'; +import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; +import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart'; import 'package:hmg_patient_app_new/features/authentication/models/resp_models/authenticated_user_resp_model.dart'; +import 'package:hmg_patient_app_new/features/common/models/family_file_request.dart'; import 'package:hmg_patient_app_new/features/medical_file/medical_file_repo.dart'; import 'package:hmg_patient_app_new/features/medical_file/models/family_file_response_model.dart'; import 'package:hmg_patient_app_new/features/medical_file/models/patient_medical_response_model.dart'; @@ -10,6 +16,7 @@ import 'package:hmg_patient_app_new/features/medical_file/models/patient_sicklea import 'package:hmg_patient_app_new/features/medical_file/models/patient_vaccine_response_model.dart'; import 'package:hmg_patient_app_new/services/dialog_service.dart'; import 'package:hmg_patient_app_new/services/error_handler_service.dart'; +import 'package:hmg_patient_app_new/services/navigation_service.dart'; class MedicalFileViewModel extends ChangeNotifier { int selectedTabIndex = 0; @@ -293,9 +300,36 @@ class MedicalFileViewModel extends ChangeNotifier { ); } - Future addFamilyFile() async { - final resultEither = await medicalFileRepo.addFamilyFile(request: {}); - resultEither.fold((failure) async => await errorHandlerService.handleError(failure: failure), (apiResponse) async {}); + Future addFamilyFile({required OTPTypeEnum otpTypeEnum, required bool isExcludedUser}) async { + AuthenticationViewModel authVM = getIt.get(); + NavigationService navigationService = getIt.get(); + FamilyFileRequest request = + await RequestUtils.getAddFamilyRequest(nationalIDorFile: authVM.nationalIdController.text, mobileNo: authVM.phoneNumberController.text, countryCode: authVM.selectedCountrySignup.countryCode); + + final resultEither = await medicalFileRepo.addFamilyFile(request: request.toJson()); + resultEither.fold((failure) async => await errorHandlerService.handleError(failure: failure), (apiResponse) async { + if (apiResponse != null && apiResponse.data != null) { + request.isPatientExcluded = apiResponse.data["IsPatientExcluded"]; + request.responseID = apiResponse.data["ReponseID"]; + _dialogService.showExceptionBottomSheet( + message: apiResponse.data['Message'], + onOkPressed: () { + print("=================== On Press Ok =================="); + authVM.sendActivationCode( + otpTypeEnum: otpTypeEnum, + nationalIdOrFileNumber: request.sharedPatientIdentificationId!, + phoneNumber: request.sharedPatientMobileNumber!, + isForRegister: false, + isExcludedUser: apiResponse.data['IsPatientExcluded'], + responseID: apiResponse.data["ReponseID"], + isFormFamilyFile: true); + + // insertFamilyData(payload: apiResponse.data![0]['ShareFamilyFileObj'], isExcludedPatient: apiResponse.data![0]['ShareFamilyFileObj']['IsPatientExcluded']); + }, + onCancelPressed: () { + navigationService.pop(); + }); + } + }); } - } diff --git a/lib/presentation/medical_file/medical_file_page.dart b/lib/presentation/medical_file/medical_file_page.dart index 18b6085..3786382 100644 --- a/lib/presentation/medical_file/medical_file_page.dart +++ b/lib/presentation/medical_file/medical_file_page.dart @@ -143,6 +143,13 @@ class _MedicalFilePageState extends State { AppCustomChipWidget( icon: AppAssets.file_icon, labelText: "${LocaleKeys.fileNo.tr(context: context)}: ${appState.getAuthenticatedUser()!.patientId}", + onChipTap: () { + navigationService.pushPage( + page: FamilyMedicalScreen( + profiles: medicalFileViewModel.patientFamilyFiles, + onSelect: (FamilyFileResponseModelLists p1) {}, + )); + }, ), AppCustomChipWidget( icon: AppAssets.checkmark_icon, @@ -769,9 +776,4 @@ class _MedicalFilePageState extends State { return Container(); } } - - getMember() { - // AuthanticationViewModel authanticationViewModel = getIt.get(); - // RequestUtils.getAddFamilyRequest(nationalIDorFile: nationalIDorFile, mobileNo: mobileNo, countryCode: countryCode, loginType: loginType); - } } diff --git a/lib/presentation/my_family/my_Family.dart b/lib/presentation/my_family/my_Family.dart index 6e4ef91..7ebd069 100644 --- a/lib/presentation/my_family/my_Family.dart +++ b/lib/presentation/my_family/my_Family.dart @@ -10,6 +10,7 @@ import 'package:hmg_patient_app_new/core/utils/validation_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/authentication/authentication_view_model.dart'; +import 'package:hmg_patient_app_new/features/medical_file/medical_file_view_model.dart'; import 'package:hmg_patient_app_new/features/medical_file/models/family_file_response_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/my_family/widget/family_cards.dart'; @@ -27,10 +28,10 @@ class FamilyMedicalScreen extends StatefulWidget { final Function(FamilyFileResponseModelLists) onSelect; const FamilyMedicalScreen({ - Key? key, + super.key, required this.profiles, required this.onSelect, - }) : super(key: key); + }); @override State createState() => _FamilyMedicalScreenState(); @@ -38,6 +39,13 @@ class FamilyMedicalScreen extends StatefulWidget { class _FamilyMedicalScreenState extends State { List tabs = [CustomTabBarModel("", LocaleKeys.medicalFile.tr()), CustomTabBarModel("", LocaleKeys.request.tr())]; + MedicalFileViewModel? medicalVM; + + @override + void initState() { + super.initState(); + medicalVM = getIt.get(); + } @override Widget build(BuildContext context) { @@ -89,9 +97,11 @@ class _FamilyMedicalScreenState extends State { AuthenticationViewModel authVm = getIt.get(); return showCommonBottomSheetWithoutHeight(context, title: "Add Family Member", + useSafeArea: true, child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, + mainAxisSize: MainAxisSize.min, children: [ "Please fill the below field to add a new family member to your profile".toText16(color: AppColors.textColor, weight: FontWeight.w500), SizedBox(height: 20.h), @@ -104,10 +114,7 @@ class _FamilyMedicalScreenState extends State { countryList: CountryEnum.values, onCountryChange: authVm.onCountryChange, ).paddingOnly(top: 8.h, bottom: 16.h), - Divider( - height: 1.h, - color: AppColors.spacerLineColor, - ), + Divider(height: 1.h, color: AppColors.spacerLineColor), TextInputWidget( labelText: LocaleKeys.nationalIdNumber.tr(), hintText: "xxxxxxxxx", @@ -123,13 +130,10 @@ class _FamilyMedicalScreenState extends State { padding: EdgeInsets.symmetric(vertical: 8.h), leadingIcon: AppAssets.student_card, ).paddingOnly(top: 8.h, bottom: 8.h), - Divider( - height: 1.h, - color: AppColors.spacerLineColor, - ), + Divider(height: 1.h, color: AppColors.spacerLineColor), TextInputWidget( labelText: LocaleKeys.phoneNumber.tr(), - hintText: "574345434", + hintText: "", controller: authVm.phoneNumberController, isEnable: true, prefix: authVm.selectedCountrySignup.countryCode, @@ -140,35 +144,7 @@ class _FamilyMedicalScreenState extends State { keyboardType: TextInputType.number, padding: EdgeInsets.symmetric(vertical: 8.h), leadingIcon: AppAssets.smart_phone, - ).paddingOnly(top: 8.h, bottom: 4), - - //TextInputWidget( - // labelText: widget.isForEmail ? LocaleKeys.email.tr() : LocaleKeys.phoneNumber.tr(), - // hintText: widget.isForEmail ? "demo@gmail.com" : "5xxxxxxxx", - // controller: widget.textController!, - // focusNode: _textFieldFocusNode, - // autoFocus: widget.autoFocus, - // padding: EdgeInsets.all(8.h), - // keyboardType: widget.isForEmail ? TextInputType.emailAddress : TextInputType.number, - // onChange: (value) { - // if (widget.onChange != null) { - // widget.onChange!(value); - // } - // }, - // onCountryChange: (value) { - // if (widget.onCountryChange != null) { - // widget.onCountryChange!(value); - // } - // }, - // isEnable: true, - // isReadOnly: widget.isFromSavedLogin, - // prefix: widget.isForEmail ? null : widget.countryCode, - // isBorderAllowed: false, - // isAllowLeadingIcon: true, - // fontSize: 13.h, - // isCountryDropDown: widget.isEnableCountryDropdown, - // leadingIcon: widget.isForEmail ? AppAssets.email : AppAssets.smart_phone, - // ) + ).paddingOnly(top: 8.h, bottom: 4.h), ], ), ), @@ -184,7 +160,10 @@ class _FamilyMedicalScreenState extends State { onOkPress: () { Navigator.of(context).pop(); }, - )) {} + )) { + // authVm.addFamilyMember(otpTypeEnum: OTPTypeEnum.sms, isExcludedUser: true); + medicalVM?.addFamilyFile(otpTypeEnum: OTPTypeEnum.sms, isExcludedUser: true); + } }, icon: AppAssets.add_icon, height: 56.h, diff --git a/lib/services/dialog_service.dart b/lib/services/dialog_service.dart index 29aee3d..474a0ec 100644 --- a/lib/services/dialog_service.dart +++ b/lib/services/dialog_service.dart @@ -73,9 +73,8 @@ class DialogServiceImp implements DialogService { Future showCommonBottomSheetWithoutH({String? label, required String message, required Function() onOkPressed, Function()? onCancelPressed}) async { final context = navigationService.navigatorKey.currentContext; if (context == null) return; - showCommonBottomSheetWithoutHeight(context, title: label ?? "", child: exceptionBottomSheetWidget(context: context, message: message, onOkPressed: onOkPressed, onCancelPressed: onCancelPressed), - callBackFunc: () { - }); + showCommonBottomSheetWithoutHeight(context, + title: label ?? "", child: exceptionBottomSheetWidget(context: context, message: message, onOkPressed: onOkPressed, onCancelPressed: onCancelPressed), callBackFunc: () {}); } @override diff --git a/lib/widgets/chip/app_custom_chip_widget.dart b/lib/widgets/chip/app_custom_chip_widget.dart index b29f6e6..099062e 100644 --- a/lib/widgets/chip/app_custom_chip_widget.dart +++ b/lib/widgets/chip/app_custom_chip_widget.dart @@ -24,6 +24,7 @@ class AppCustomChipWidget extends StatelessWidget { this.deleteIconColor = AppColors.textColor, this.deleteIconHasColor = false, this.padding = EdgeInsets.zero, + this.onChipTap }); final String? labelText; @@ -40,74 +41,78 @@ class AppCustomChipWidget extends StatelessWidget { final bool deleteIconHasColor; final OutlinedBorder? shape; final EdgeInsets? padding; + final void Function()? onChipTap; @override Widget build(BuildContext context) { - return ChipTheme( - data: ChipThemeData( - padding: EdgeInsets.all(0.0), - shape: SmoothRectangleBorder( - side: BorderSide( - width: 0.0, - color: Colors.transparent, // Crucially, set color to transparent - style: BorderStyle.none, + return GestureDetector( + onTap: onChipTap, + child: ChipTheme( + data: ChipThemeData( + padding: EdgeInsets.all(0.0), + shape: SmoothRectangleBorder( + side: BorderSide( + width: 0.0, + color: Colors.transparent, // Crucially, set color to transparent + style: BorderStyle.none, + ), + borderRadius: BorderRadius.circular(10.0), // Apply a border radius of 16.0 ), - borderRadius: BorderRadius.circular(10.0), // Apply a border radius of 16.0 ), + child: icon.isNotEmpty + ? Chip( + avatar: icon.isNotEmpty + ? Utils.buildSvgWithAssets( + icon: icon, + width: iconSize.h, + height: iconSize.h, + iconColor: iconHasColor ? iconColor : null) + : SizedBox.shrink(), + label: richText ?? + labelText!.toText10( + weight: FontWeight.w500, + letterSpacing: -0.64, + color: textColor), + // padding: EdgeInsets.all(0.0), + padding: padding, + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + labelPadding: EdgeInsets.only( + left: -4.h, + right: deleteIcon?.isNotEmpty == true ? 2.h : 8.h), + backgroundColor: backgroundColor, + shape: shape, + deleteIcon: deleteIcon?.isNotEmpty == true + ? Utils.buildSvgWithAssets( + icon: deleteIcon!, + width: deleteIconSize!.width!.h, + height: deleteIconSize!.height.h, + iconColor: deleteIconHasColor ? deleteIconColor : null) + : null, + onDeleted: deleteIcon?.isNotEmpty == true ? () {} : null, + ) + : Chip( + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + label: richText ?? + labelText!.toText10( + weight: FontWeight.w500, + letterSpacing: -0.64, + color: textColor), + padding: EdgeInsets.all(0.0), + backgroundColor: backgroundColor, + shape: shape, + labelPadding: EdgeInsets.only( + left: 8.h, + right: deleteIcon?.isNotEmpty == true ? -2.h : 8.h), + deleteIcon: deleteIcon?.isNotEmpty == true + ? Utils.buildSvgWithAssets( + icon: deleteIcon!, + width: deleteIconSize!.width.h, + height: deleteIconSize!.height.h, + iconColor: deleteIconHasColor ? deleteIconColor : null) + : null, + onDeleted: deleteIcon?.isNotEmpty == true ? () {} : null, + ), ), - child: icon.isNotEmpty - ? Chip( - avatar: icon.isNotEmpty - ? Utils.buildSvgWithAssets( - icon: icon, - width: iconSize.h, - height: iconSize.h, - iconColor: iconHasColor ? iconColor : null) - : SizedBox.shrink(), - label: richText ?? - labelText!.toText10( - weight: FontWeight.w500, - letterSpacing: -0.64, - color: textColor), - // padding: EdgeInsets.all(0.0), - padding: padding, - materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, - labelPadding: EdgeInsets.only( - left: -4.h, - right: deleteIcon?.isNotEmpty == true ? 2.h : 8.h), - backgroundColor: backgroundColor, - shape: shape, - deleteIcon: deleteIcon?.isNotEmpty == true - ? Utils.buildSvgWithAssets( - icon: deleteIcon!, - width: deleteIconSize!.width!.h, - height: deleteIconSize!.height.h, - iconColor: deleteIconHasColor ? deleteIconColor : null) - : null, - onDeleted: deleteIcon?.isNotEmpty == true ? () {} : null, - ) - : Chip( - materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, - label: richText ?? - labelText!.toText10( - weight: FontWeight.w500, - letterSpacing: -0.64, - color: textColor), - padding: EdgeInsets.all(0.0), - backgroundColor: backgroundColor, - shape: shape, - labelPadding: EdgeInsets.only( - left: 8.h, - right: deleteIcon?.isNotEmpty == true ? -2.h : 8.h), - deleteIcon: deleteIcon?.isNotEmpty == true - ? Utils.buildSvgWithAssets( - icon: deleteIcon!, - width: deleteIconSize!.width.h, - height: deleteIconSize!.height.h, - iconColor: deleteIconHasColor ? deleteIconColor : null) - : null, - onDeleted: deleteIcon?.isNotEmpty == true ? () {} : null, - ), ); } } diff --git a/lib/widgets/common_bottom_sheet.dart b/lib/widgets/common_bottom_sheet.dart index c50ffad..c6db474 100644 --- a/lib/widgets/common_bottom_sheet.dart +++ b/lib/widgets/common_bottom_sheet.dart @@ -105,54 +105,136 @@ class ButtonSheetContent extends StatelessWidget { } void showCommonBottomSheetWithoutHeight( - BuildContext context, { - required Widget child, - required VoidCallback callBackFunc, - String title = "", - bool isCloseButtonVisible = true, - bool isFullScreen = true, - bool isDismissible = true, - Widget? titleWidget, -}) { + BuildContext context, { + required Widget child, + required VoidCallback callBackFunc, + String title = "", + bool isCloseButtonVisible = true, + bool isFullScreen = true, + bool isDismissible = true, + Widget? titleWidget, + bool useSafeArea = false, + }) { showModalBottomSheet( - sheetAnimationStyle: AnimationStyle( - duration: Duration(milliseconds: 500), // Custom animation duration - reverseDuration: Duration(milliseconds: 300), // Custom reverse animation duration - ), - context: context, - isScrollControlled: true, - showDragHandle: false, - isDismissible: isDismissible, - backgroundColor: AppColors.bottomSheetBgColor, - builder: (BuildContext context) { - return SafeArea( - top: false, - left: false, - right: false, - child: isCloseButtonVisible - ? Container( - padding: EdgeInsets.only(left: 24, top: 24, right: 24, bottom: 12), - decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.bottomSheetBgColor, borderRadius: 24.h), - child: Column( - mainAxisSize: MainAxisSize.min, - spacing: 16.h, + sheetAnimationStyle: AnimationStyle( + duration: Duration(milliseconds: 500), + reverseDuration: Duration(milliseconds: 300), + ), + context: context, + isScrollControlled: true, + showDragHandle: false, + isDismissible: isDismissible, + backgroundColor: AppColors.bottomSheetBgColor, + useSafeArea: useSafeArea, + builder: (BuildContext context) { + return SafeArea( + top: false, + left: false, + right: false, + child: Padding( + padding: EdgeInsets.only( + bottom: MediaQuery.of(context).viewInsets.bottom, + ), + child: SingleChildScrollView( + physics: ClampingScrollPhysics(), + child: isCloseButtonVisible + ? Container( + padding: EdgeInsets.only( + left: 24, + top: 24, + right: 24, + bottom: 12, + ), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.bottomSheetBgColor, + borderRadius: 24.h, + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - titleWidget ?? Expanded(child: title.toText20(weight: FontWeight.w600)), - Utils.buildSvgWithAssets(icon: AppAssets.close_bottom_sheet_icon, iconColor: Color(0xff2B353E)).onPress(() { - Navigator.of(context).pop(); - }), - ], - ), - child, + titleWidget ?? + Expanded( + child: title.toText20(weight: FontWeight.w600), + ), + Utils.buildSvgWithAssets( + icon: AppAssets.close_bottom_sheet_icon, + iconColor: Color(0xff2B353E), + ).onPress(() { + Navigator.of(context).pop(); + }), ], - )) - : child, - ); - }).then((value) { + ), + SizedBox(height: 16.h), + child, + ], + ), + ) + : child, + ), + ), + ); + }, + ).then((value) { callBackFunc(); }); } + +// void showCommonBottomSheetWithoutHeight( +// BuildContext context, { +// required Widget child, +// required VoidCallback callBackFunc, +// String title = "", +// bool isCloseButtonVisible = true, +// bool isFullScreen = true, +// bool isDismissible = true, +// Widget? titleWidget, +// bool useSafeArea = false, +// +// }) { +// showModalBottomSheet( +// sheetAnimationStyle: AnimationStyle( +// duration: Duration(milliseconds: 500), // Custom animation duration +// reverseDuration: Duration(milliseconds: 300), // Custom reverse animation duration +// ), +// context: context, +// isScrollControlled: true, +// showDragHandle: false, +// isDismissible: isDismissible, +// backgroundColor: AppColors.bottomSheetBgColor, +// useSafeArea: useSafeArea, +// builder: (BuildContext context) { +// return SafeArea( +// top: false, +// left: false, +// right: false, +// child: isCloseButtonVisible +// ? Container( +// padding: EdgeInsets.only(left: 24, top: 24, right: 24, bottom: 12), +// decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.bottomSheetBgColor, borderRadius: 24.h), +// child: Column( +// mainAxisSize: MainAxisSize.min, +// spacing: 16.h, +// children: [ +// Row( +// mainAxisAlignment: MainAxisAlignment.spaceBetween, +// crossAxisAlignment: CrossAxisAlignment.center, +// children: [ +// titleWidget ?? Expanded(child: title.toText20(weight: FontWeight.w600)), +// Utils.buildSvgWithAssets(icon: AppAssets.close_bottom_sheet_icon, iconColor: Color(0xff2B353E)).onPress(() { +// Navigator.of(context).pop(); +// }), +// ], +// ), +// child, +// ], +// )) +// : child, +// ); +// }).then((value) { +// callBackFunc(); +// }); +// }