diff --git a/assets/images/svg/not_found.svg b/assets/images/svg/not_found.svg new file mode 100644 index 0000000..80aed53 --- /dev/null +++ b/assets/images/svg/not_found.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/lib/core/api/api_client.dart b/lib/core/api/api_client.dart index 425f1bd..7555400 100644 --- a/lib/core/api/api_client.dart +++ b/lib/core/api/api_client.dart @@ -7,13 +7,16 @@ import 'package:hmg_patient_app_new/core/api_consts.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/utils/utils.dart'; +import 'package:hmg_patient_app_new/routes/app_routes.dart'; import 'package:hmg_patient_app_new/services/analytics/analytics_service.dart'; import 'package:hmg_patient_app_new/services/logger_service.dart'; +import 'package:hmg_patient_app_new/services/navigation_service.dart'; import 'package:http/http.dart' as http; import '../exceptions/api_failure.dart'; abstract class ApiClient { + static final NavigationService _navigationService = getIt.get(); Future post( String endPoint, { required Map body, @@ -105,7 +108,7 @@ class ApiClientImp implements ApiClient { url = ApiConsts.baseUrl + endPoint; } } - try { + // try { var user = _appState.getAuthenticatedUser(); Map headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}; if (!isExternal) { @@ -261,6 +264,8 @@ class ApiClientImp implements ApiClient { logApiEndpointError(endPoint, parsed['message'] ?? parsed['message'], statusCode); } } + } else if (!parsed['IsAuthenticated']) { + } else { if (parsed['SameClinicApptList'] != null) { onSuccess(parsed, statusCode, messageStatus: parsed['MessageStatus'], errorMessage: parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']); @@ -285,16 +290,20 @@ class ApiClientImp implements ApiClient { } } } - } catch (e, stackTrace) { - _loggerService.errorLogs(stackTrace.toString()); - if (e.toString().contains("ClientException")) { - onFailure('ClientException: Something went wrong, Please try again', -1, failureType: InvalidCredentials('ClientException: Something went wrong, plase try again')); - _analytics.errorTracking.log("internet_connectivity", error: "no internet available"); - } else { - onFailure(e.toString(), -1); - } - _analytics.errorTracking.log(endPoint, error: "api exception: $e - API Path: $url"); - } + // } catch (e, stackTrace) { + // _loggerService.errorLogs(stackTrace.toString()); + // if (e.toString().contains("ClientException")) { + // onFailure('ClientException: Something went wrong, Please try again', -1, failureType: InvalidCredentials('ClientException: Something went wrong, plase try again')); + // _analytics.errorTracking.log("internet_connectivity", error: "no internet available"); + // } else { + // onFailure(e.toString(), -1); + // } + // _analytics.errorTracking.log(endPoint, error: "api exception: $e - API Path: $url"); + // } + } + + logout() async { + ApiClient._navigationService.pushAndReplace(AppRoutes.landingScreen); } @override diff --git a/lib/core/api_consts.dart b/lib/core/api_consts.dart index 3b3ed28..99f53d3 100644 --- a/lib/core/api_consts.dart +++ b/lib/core/api_consts.dart @@ -726,7 +726,7 @@ const DEACTIVATE_ACCOUNT = 'Services/Patients.svc/REST/PatientAppleActivation_In class ApiConsts { static const maxSmallScreen = 660; - static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.prod; + static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.uat; // static String baseUrl = 'https://uat.hmgwebservices.com/'; // HIS API URL UAT diff --git a/lib/core/enums.dart b/lib/core/enums.dart index 3f7fee7..7ed275a 100644 --- a/lib/core/enums.dart +++ b/lib/core/enums.dart @@ -104,6 +104,8 @@ extension LoginTypeExtension on LoginTypeEnum { static LoginTypeEnum? fromValue(int value) { switch (value) { + case 0: + return LoginTypeEnum.sms; case 1: return LoginTypeEnum.sms; case 2: diff --git a/lib/core/utils/utils.dart b/lib/core/utils/utils.dart index 1b01001..75c0cf9 100644 --- a/lib/core/utils/utils.dart +++ b/lib/core/utils/utils.dart @@ -291,7 +291,7 @@ class Utils { mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ - SvgPicture.asset('assets/images/NoDataAvailableIcon.svg', width: 150.0, height: 150.0), + SvgPicture.asset('assets/images/svg/not_found.svg', width: 150.0, height: 150.0), (errorText ?? LocaleKeys.noDataAvailable.tr()).toText16(isCenter: true).paddingOnly(top: 15), ], ).center; @@ -310,6 +310,19 @@ class Utils { ).center; } + static Widget getSuccessWidget({String? loadingText}) { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Lottie.asset(AppAnimations.checkmark, repeat: true, reverse: false, frameRate: FrameRate(60), width: 100.h, height: 100.h, fit: BoxFit.fill), + SizedBox(height: 8.h), + (loadingText ?? LocaleKeys.loadingText.tr()).toText16(color: AppColors.blackColor), + SizedBox(height: 8.h), + ], + ).center; + } + static bool isVidaPlusProject(AppState appState, int projectID) { bool isVidaPlus = false; for (var element in appState.vidaPlusProjectList) { diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index cb6ce72..e36dbeb 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -34,21 +34,21 @@ extension EmailValidator on String { ), ); - Widget toText10({Color? color, bool isBold = false, bool isUnderLine = false, int? maxlines, FontStyle? fontStyle, TextOverflow? textOverflow}) => Text( + Widget toText10({Color? color, FontWeight? weight, bool isBold = false, bool isUnderLine = false, int? maxlines, FontStyle? fontStyle, TextOverflow? textOverflow, double letterSpacing = -1}) => Text( this, maxLines: maxlines, overflow: textOverflow, style: TextStyle( fontSize: 10.fSize, fontStyle: fontStyle ?? FontStyle.normal, - fontWeight: isBold ? FontWeight.bold : FontWeight.normal, + fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.normal), color: color ?? AppColors.blackColor, - letterSpacing: -1, + letterSpacing: letterSpacing, decoration: isUnderLine ? TextDecoration.underline : null, decorationColor: color ?? AppColors.blackColor), ); - Widget toText11({Color? color, FontWeight? weight, bool isUnderLine = false, bool isCenter = false, bool isBold = false, int maxLine = 0, double letterSpacing = 0.64}) => Text( + Widget toText11({Color? color, FontWeight? weight, bool isUnderLine = false, bool isCenter = false, bool isBold = false, int maxLine = 0, double letterSpacing = -1}) => Text( this, textAlign: isCenter ? TextAlign.center : null, maxLines: (maxLine > 0) ? maxLine : null, @@ -57,7 +57,7 @@ extension EmailValidator on String { fontSize: 11.fSize, fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.normal), color: color ?? AppColors.blackColor, - letterSpacing: -1, + letterSpacing: letterSpacing, decoration: isUnderLine ? TextDecoration.underline : null, ), ); @@ -125,6 +125,8 @@ extension EmailValidator on String { bool isBold = false, bool isCenter = false, int maxLine = 0, + FontWeight? weight, + double? letterSpacing = -1 }) => Text( this, @@ -132,9 +134,9 @@ extension EmailValidator on String { maxLines: (maxLine > 0) ? maxLine : null, style: TextStyle( fontSize: 13.fSize, - fontWeight: isBold ? FontWeight.bold : FontWeight.normal, + fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.normal), color: color ?? AppColors.blackColor, - letterSpacing: -1, + letterSpacing: letterSpacing, decoration: isUnderLine ? TextDecoration.underline : null), ); diff --git a/lib/features/authentication/authentication_view_model.dart b/lib/features/authentication/authentication_view_model.dart index 07c8980..fbfa2b1 100644 --- a/lib/features/authentication/authentication_view_model.dart +++ b/lib/features/authentication/authentication_view_model.dart @@ -165,7 +165,8 @@ class AuthenticationViewModel extends ChangeNotifier { Future selectDeviceImei({required Function(dynamic data) onSuccess, Function(String)? onError}) async { // LoadingUtils.showFullScreenLoading(); // String firebaseToken = _appState.deviceToken; - String firebaseToken = await Utils.getStringFromPrefs(CacheConst.pushToken); + // String firebaseToken = await Utils.getStringFromPrefs(CacheConst.pushToken); + String firebaseToken = "fY1fq_cITMmUCztA3UKKL9:APA91bEb2ZcdCPQPq3QsA0NW6a6btFvN-JjB1Pn3ZCoCzBMmVUhhh1ZQMtRn9tYPQ5G-jHDLiEpVAlBuRCVMkLDxa-zijsqbIui-4A-ynwclDWGFT4bUHTc"; // == "" // ? "dOGRRszQQMGe_9wA5Hx3kO:APA91bFV5IcIJXvcCXXk0tc2ddtZgWwCPq7sGSuPr-YW7iiJpQZKgFGN9GAzCVOWL8MfheaP1slE8MdxB7lczdPBGdONQ7WbMmhgHcsUCUktq-hsapGXXqc" // : _appState.deviceToken; @@ -174,7 +175,9 @@ class AuthenticationViewModel extends ChangeNotifier { result.fold( (failure) async { // LoadingUtils.hideFullScreenLoader(); - await _errorHandlerService.handleError(failure: failure); + // await _errorHandlerService.handleError(failure: failure); + LoadingUtils.hideFullScreenLoader(); + _navigationService.pushPage(page: LoginScreen()); }, (apiResponse) { // LoadingUtils.hideFullScreenLoader(); @@ -237,9 +240,9 @@ class AuthenticationViewModel extends ChangeNotifier { Future checkUserAuthentication({required OTPTypeEnum otpTypeEnum, Function(dynamic)? onSuccess, Function(String)? onError}) async { // TODO: THIS SHOULD BE REMOVED LATER ON AND PASSED FROM APP STATE DIRECTLY INTO API CLIENT. BECAUSE THIS API ONLY NEEDS FEW PARAMS FROM USER - if (phoneNumberController.text.isEmpty) { - phoneNumberController.text = "504278212"; - } + // if (phoneNumberController.text.isEmpty) { + // phoneNumberController.text = "504278212"; + // } bool isValidated = ValidationUtils.isValidatePhoneAndId( phoneNumber: phoneNumberController.text, nationalId: nationalIdController.text, diff --git a/lib/features/insurance/insurance_repo.dart b/lib/features/insurance/insurance_repo.dart index 536556f..68b53e4 100644 --- a/lib/features/insurance/insurance_repo.dart +++ b/lib/features/insurance/insurance_repo.dart @@ -24,23 +24,7 @@ class InsuranceRepoImp implements InsuranceRepo { @override Future>>> getPatientInsuranceDetails({required String patientId}) async { - final mapDevice = { - "isDentalAllowedBackend": false, - "VersionID": 50.0, - "Channel": 3, - "LanguageID": 2, - "IPAdress": "10.20.10.20", - "generalid": "Cs2020@2016\$2958", - "Latitude": 0.0, - "Longitude": 0.0, - "DeviceTypeID": 1, - "PatientType": 1, - "PatientTypeID": 1, - "TokenID": "@dm!n", - "PatientID": "3628599", - "PatientOutSA": "0", - "SessionID": "03478TYC02N80874CTYN04883475!?" - }; + Map mapDevice = {}; try { GenericApiModel>? apiResponse; @@ -77,29 +61,11 @@ class InsuranceRepoImp implements InsuranceRepo { } catch (e) { return Left(UnknownFailure(e.toString())); } - - throw UnimplementedError(); } @override Future>>> getPatientInsuranceCardHistory({required String patientId}) async { - final mapDevice = { - "isDentalAllowedBackend": false, - "VersionID": 50.0, - "Channel": 3, - "LanguageID": 2, - "IPAdress": "10.20.10.20", - "generalid": "Cs2020@2016\$2958", - "Latitude": 0.0, - "Longitude": 0.0, - "DeviceTypeID": 1, - "PatientType": 1, - "PatientTypeID": 1, - "TokenID": "@dm!n", - "PatientID": "3628599", - "PatientOutSA": "0", - "SessionID": "03478TYC02N80874CTYN04883475!?" - }; + Map mapDevice = {}; try { GenericApiModel>? apiResponse; @@ -140,28 +106,7 @@ class InsuranceRepoImp implements InsuranceRepo { @override Future>> getPatientInsuranceDetailsForUpdate({required String patientId, required String identificationNo}) async { - final mapDevice = { - "SetupID": "010266", - "ProjectID": 15, - "PatientIdentificationID": "2464169354", - "isDentalAllowedBackend": false, - "PatientID": "3628599", - "IsFamily": false, - "ParentID": 0, - "VersionID": 18.8, - "Channel": 3, - "LanguageID": 2, - "IPAdress": "10.20.10.20", - "generalid": "Cs2020@2016\$2958", - "Latitude": 0.0, - "Longitude": 0.0, - "DeviceTypeID": 2, - "PatientType": 1, - "PatientTypeID": 1, - "TokenID": "@dm!n", - "PatientOutSA": 0, - "SessionID": "eyy7u090a9dfadsghfpsadiuhf234" - }; + final mapDevice = {"SetupID": "010266", "ProjectID": 15, "PatientIdentificationID": identificationNo, "IsFamily": false, "ParentID": 0}; try { GenericApiModel? apiResponse; diff --git a/lib/features/insurance/insurance_view_model.dart b/lib/features/insurance/insurance_view_model.dart index 169d967..527c180 100644 --- a/lib/features/insurance/insurance_view_model.dart +++ b/lib/features/insurance/insurance_view_model.dart @@ -89,8 +89,8 @@ class InsuranceViewModel extends ChangeNotifier { ); } - Future getPatientInsuranceDetailsForUpdate({Function(dynamic)? onSuccess, Function(String)? onError}) async { - final result = await insuranceRepo.getPatientInsuranceDetailsForUpdate(patientId: "1231755", identificationNo: ""); + Future getPatientInsuranceDetailsForUpdate(String patientID, String identificationNo, {Function(dynamic)? onSuccess, Function(String)? onError}) async { + final result = await insuranceRepo.getPatientInsuranceDetailsForUpdate(patientId: patientID, identificationNo: identificationNo); result.fold( (failure) async => await errorHandlerService.handleError(failure: failure), diff --git a/lib/features/lab/lab_repo.dart b/lib/features/lab/lab_repo.dart index d746c69..ede2ec8 100644 --- a/lib/features/lab/lab_repo.dart +++ b/lib/features/lab/lab_repo.dart @@ -18,23 +18,7 @@ class LabRepoImp implements LabRepo { @override Future>>> getPatientLabOrders({required String patientId}) async { - final mapDevice = { - "isDentalAllowedBackend": false, - "VersionID": 50.0, - "Channel": 3, - "LanguageID": 2, - "IPAdress": "10.20.10.20", - "generalid": "Cs2020@2016\$2958", - "Latitude": 0.0, - "Longitude": 0.0, - "DeviceTypeID": 1, - "PatientType": 1, - "PatientTypeID": 1, - "TokenID": "@dm!n", - "PatientID": "1018977", - "PatientOutSA": "0", - "SessionID": "03478TYC02N80874CTYN04883475!?" - }; + Map mapDevice = {}; try { GenericApiModel>? apiResponse; @@ -52,10 +36,7 @@ class LabRepoImp implements LabRepo { throw Exception("lab list is empty"); } - final labOrders = list - .map((item) => PatientLabOrdersResponseModel.fromJson(item as Map)) - .toList() - .cast(); + final labOrders = list.map((item) => PatientLabOrdersResponseModel.fromJson(item as Map)).toList().cast(); apiResponse = GenericApiModel>( messageStatus: messageStatus, diff --git a/lib/features/my_appointments/my_appointments_repo.dart b/lib/features/my_appointments/my_appointments_repo.dart index 5a55909..0815b94 100644 --- a/lib/features/my_appointments/my_appointments_repo.dart +++ b/lib/features/my_appointments/my_appointments_repo.dart @@ -9,10 +9,9 @@ import 'package:hmg_patient_app_new/services/logger_service.dart'; abstract class MyAppointmentsRepo { Future>>> getPatientAppointments( - {required String patientId, required bool isActiveAppointment, required bool isArrivedAppointments}); + {required bool isActiveAppointment, required bool isArrivedAppointments}); - Future>> getPatientShareAppointment( - {required String patientId, required int projectID, required int clinicID, required String appointmentNo}); + Future>> getPatientShareAppointment({required int projectID, required int clinicID, required String appointmentNo}); Future>> createAdvancePayment( {required String paymentMethodName, @@ -26,7 +25,9 @@ abstract class MyAppointmentsRepo { Future>> addAdvanceNumberRequest({required String advanceNumber, required String paymentReference, required String appointmentNo}); - Future>> generateAppointmentQR({required String clinicID, required String projectID, required String appointmentNo, required int isFollowUp}); + Future>> generateAppointmentQR({required int clinicID, required int projectID, required String appointmentNo, required int isFollowUp}); + + Future>> cancelAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel}); } class MyAppointmentsRepoImp implements MyAppointmentsRepo { @@ -37,8 +38,8 @@ class MyAppointmentsRepoImp implements MyAppointmentsRepo { @override Future>>> getPatientAppointments( - {required String patientId, required bool isActiveAppointment, required bool isArrivedAppointments}) async { - final mapDevice = { + {required bool isActiveAppointment, required bool isArrivedAppointments}) async { + Map mapDevice = { "IsActiveAppointment": isActiveAppointment, "isDentalAllowedBackend": false, "PatientTypeID": 1, @@ -61,9 +62,9 @@ class MyAppointmentsRepoImp implements MyAppointmentsRepo { onSuccess: (response, statusCode, {messageStatus, errorMessage}) { try { final list = response['AppoimentAllHistoryResultList']; - if (list == null || list.isEmpty) { - throw Exception("Appointments list is empty"); - } + // if (list == null || list.isEmpty) { + // throw Exception("Appointments list is empty"); + // } final appointmentsList = list.map((item) => PatientAppointmentHistoryResponseModel.fromJson(item as Map)).toList().cast(); @@ -87,19 +88,8 @@ class MyAppointmentsRepoImp implements MyAppointmentsRepo { } @override - Future>> getPatientShareAppointment( - {required String patientId, required int projectID, required int clinicID, required String appointmentNo}) async { - final mapRequest = { - "ProjectID": projectID, - "ClinicID": clinicID, - "AppointmentNo": appointmentNo, - "IsActiveAppointment": true, - "PatientOutSA": 0, - "isDentalAllowedBackend": false, - "PatientID": patientId, - "PatientTypeID": 1, - "PatientType": 1, - }; + Future>> getPatientShareAppointment({required int projectID, required int clinicID, required String appointmentNo}) async { + Map mapRequest = {"ProjectID": projectID, "ClinicID": clinicID, "AppointmentNo": appointmentNo, "IsActiveAppointment": true}; try { GenericApiModel? apiResponse; @@ -139,8 +129,6 @@ class MyAppointmentsRepoImp implements MyAppointmentsRepo { } catch (e) { return Left(UnknownFailure(e.toString())); } - - throw UnimplementedError(); } @override @@ -154,7 +142,7 @@ class MyAppointmentsRepoImp implements MyAppointmentsRepo { required String patientID, required int patientType, }) async { - final requestBody = { + Map requestBody = { "ProjectID": projectID, "OnlineCheckInAppointment": { "AppointmentNo": appointmentNo, @@ -202,7 +190,7 @@ class MyAppointmentsRepoImp implements MyAppointmentsRepo { @override Future> addAdvanceNumberRequest({required String advanceNumber, required String paymentReference, required String appointmentNo}) async { - final requestBody = { + Map requestBody = { "AdvanceNumber": advanceNumber, "AdvanceNumber_VP": advanceNumber, "PaymentReferenceNumber": paymentReference, @@ -240,8 +228,8 @@ class MyAppointmentsRepoImp implements MyAppointmentsRepo { } @override - Future> generateAppointmentQR({required String clinicID, required String projectID, required String appointmentNo, required int isFollowUp}) async { - final requestBody = { + Future> generateAppointmentQR({required int clinicID, required int projectID, required String appointmentNo, required int isFollowUp}) async { + Map requestBody = { "AppointmentNo": appointmentNo, "ClinicID": clinicID, "ProjectID": projectID, @@ -277,4 +265,49 @@ class MyAppointmentsRepoImp implements MyAppointmentsRepo { return Left(UnknownFailure(e.toString())); } } + + @override + Future> cancelAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel}) async { + Map requestBody = { + "AppointmentID": patientAppointmentHistoryResponseModel.appointmentNo, + "ClinicID": patientAppointmentHistoryResponseModel.clinicID, + "ProjectID": patientAppointmentHistoryResponseModel.projectID, + "CancelToReschadual": false, + "EndTime": patientAppointmentHistoryResponseModel.endTime, + "StartTime": patientAppointmentHistoryResponseModel.startTime, + "DoctorID": patientAppointmentHistoryResponseModel.doctorID, + "IsForLiveCare": patientAppointmentHistoryResponseModel.isLiveCareAppointment, + "OriginalClinicID": patientAppointmentHistoryResponseModel.originalClinicID, + "OriginalProjectID": patientAppointmentHistoryResponseModel.originalProjectID + }; + + try { + GenericApiModel? apiResponse; + Failure? failure; + await apiClient.post( + CANCEL_APPOINTMENT, + body: requestBody, + onFailure: (error, statusCode, {messageStatus, failureType}) { + failure = failureType; + }, + onSuccess: (response, statusCode, {messageStatus, errorMessage}) { + try { + apiResponse = GenericApiModel( + messageStatus: messageStatus, + statusCode: statusCode, + errorMessage: null, + data: response, + ); + } catch (e) { + failure = DataParsingFailure(e.toString()); + } + }, + ); + if (failure != null) return Left(failure!); + if (apiResponse == null) return Left(ServerFailure("Unknown error")); + return Right(apiResponse!); + } catch (e) { + return Left(UnknownFailure(e.toString())); + } + } } diff --git a/lib/features/my_appointments/my_appointments_view_model.dart b/lib/features/my_appointments/my_appointments_view_model.dart index 439a8e8..5c952e9 100644 --- a/lib/features/my_appointments/my_appointments_view_model.dart +++ b/lib/features/my_appointments/my_appointments_view_model.dart @@ -49,7 +49,7 @@ class MyAppointmentsViewModel extends ChangeNotifier { } Future getPatientAppointments(bool isActiveAppointment, bool isArrivedAppointments, {Function(dynamic)? onSuccess, Function(String)? onError}) async { - final result = await myAppointmentsRepo.getPatientAppointments(patientId: "3628599", isActiveAppointment: isActiveAppointment, isArrivedAppointments: isArrivedAppointments); + final result = await myAppointmentsRepo.getPatientAppointments(isActiveAppointment: isActiveAppointment, isArrivedAppointments: isArrivedAppointments); result.fold( (failure) async => await errorHandlerService.handleError(failure: failure), @@ -69,7 +69,7 @@ class MyAppointmentsViewModel extends ChangeNotifier { } Future getPatientShareAppointment(int projectID, int clinicID, String appointmentNo, {Function(dynamic)? onSuccess, Function(String)? onError}) async { - final result = await myAppointmentsRepo.getPatientShareAppointment(patientId: "3628599", projectID: projectID, clinicID: clinicID, appointmentNo: appointmentNo); + final result = await myAppointmentsRepo.getPatientShareAppointment(projectID: projectID, clinicID: clinicID, appointmentNo: appointmentNo); result.fold( (failure) async => await errorHandlerService.handleError(failure: failure), @@ -108,7 +108,7 @@ class MyAppointmentsViewModel extends ChangeNotifier { } Future generateAppointmentQR( - {required String clinicID, required String projectID, required String appointmentNo, required int isFollowUp, Function(dynamic)? onSuccess, Function(String)? onError}) async { + {required int clinicID, required int projectID, required String appointmentNo, required int isFollowUp, Function(dynamic)? onSuccess, Function(String)? onError}) async { final result = await myAppointmentsRepo.generateAppointmentQR(clinicID: clinicID, projectID: projectID, appointmentNo: appointmentNo, isFollowUp: isFollowUp); result.fold( @@ -126,6 +126,25 @@ class MyAppointmentsViewModel extends ChangeNotifier { ); } + Future cancelAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel, Function(dynamic)? onSuccess, Function(String)? onError}) async { + final result = await myAppointmentsRepo.cancelAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel); + + result.fold( + (failure) async => await errorHandlerService.handleError(failure: failure), + (apiResponse) { + if (apiResponse.messageStatus == 2) { + onError!(apiResponse.errorMessage!); + // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {}); + } else if (apiResponse.messageStatus == 1) { + notifyListeners(); + if (onSuccess != null) { + onSuccess(apiResponse); + } + } + }, + ); + } + Future createAdvancePayment( {required String paymentMethodName, required int projectID, diff --git a/lib/features/radiology/radiology_repo.dart b/lib/features/radiology/radiology_repo.dart index 2917dfd..9db803d 100644 --- a/lib/features/radiology/radiology_repo.dart +++ b/lib/features/radiology/radiology_repo.dart @@ -18,23 +18,7 @@ class RadiologyRepoImp implements RadiologyRepo { @override Future>>> getPatientRadiologyOrders({required String patientId}) async { - final mapDevice = { - "isDentalAllowedBackend": false, - "VersionID": 50.0, - "Channel": 3, - "LanguageID": 2, - "IPAdress": "10.20.10.20", - "generalid": "Cs2020@2016\$2958", - "Latitude": 0.0, - "Longitude": 0.0, - "DeviceTypeID": 1, - "PatientType": 1, - "PatientTypeID": 1, - "TokenID": "@dm!n", - "PatientID": "1018977", - "PatientOutSA": "0", - "SessionID": "03478TYC02N80874CTYN04883475!?" - }; + Map mapDevice = {}; try { GenericApiModel>? apiResponse; diff --git a/lib/presentation/appointments/appointment_details_page.dart b/lib/presentation/appointments/appointment_details_page.dart index 1413765..4255c71 100644 --- a/lib/presentation/appointments/appointment_details_page.dart +++ b/lib/presentation/appointments/appointment_details_page.dart @@ -16,6 +16,7 @@ import 'package:hmg_patient_app_new/presentation/appointments/appointment_paymen import 'package:hmg_patient_app_new/presentation/appointments/widgets/appointment_doctor_card.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; +import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart'; import 'package:maps_launcher/maps_launcher.dart'; import 'package:provider/provider.dart'; @@ -58,7 +59,33 @@ class _AppointmentDetailsPageState extends State { AppointmentDoctorCard( patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel, onAskDoctorTap: () {}, - onCancelTap: () {}, + onCancelTap: () async { + showCommonBottomSheet(context, + child: Utils.getLoadingWidget(), + callBackFunc: (str) {}, + title: "", + height: ResponsiveExtension.screenHeight * 0.3, + isCloseButtonVisible: false, + isDismissible: false, + isFullScreen: false); + await myAppointmentsViewModel.cancelAppointment( + patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel, + onSuccess: (apiResponse) { + Navigator.of(context).pop(); + showCommonBottomSheet(context, + child: Utils.getSuccessWidget(loadingText: "Appointment Cancelled Successfully".needTranslation), + callBackFunc: (str) { + }, + title: "", + height: ResponsiveExtension.screenHeight * 0.3, + isCloseButtonVisible: false, + isDismissible: false, + isFullScreen: false, + isSuccessDialog: true); + }); + Navigator.of(context).pop(); + Navigator.of(context).pop(); + }, onRescheduleTap: () {}, ), SizedBox(height: 16.h), diff --git a/lib/presentation/appointments/appointment_payment_page.dart b/lib/presentation/appointments/appointment_payment_page.dart index 609d881..861d5b9 100644 --- a/lib/presentation/appointments/appointment_payment_page.dart +++ b/lib/presentation/appointments/appointment_payment_page.dart @@ -354,8 +354,8 @@ class _AppointmentPaymentPageState extends State { print(value); await myAppointmentsViewModel.addAdvanceNumberRequest( advanceNumber: Utils.isVidaPlusProject(appState, widget.patientAppointmentHistoryResponseModel.projectID) - ? value['data']['OnlineCheckInAppointments'][0]['AdvanceNumber_VP'].toString() - : value['data']['OnlineCheckInAppointments'][0]['AdvanceNumber'].toString(), + ? value.data['OnlineCheckInAppointments'][0]['AdvanceNumber_VP'].toString() + : value.data['OnlineCheckInAppointments'][0]['AdvanceNumber'].toString(), paymentReference: payfortViewModel.payfortCheckPaymentStatusResponseModel!.fortId!, appointmentNo: widget.patientAppointmentHistoryResponseModel.appointmentNo.toString(), onSuccess: (value) async { @@ -394,12 +394,12 @@ class _AppointmentPaymentPageState extends State { "Appointment check in", transID, widget.patientAppointmentHistoryResponseModel.projectID.toString(), - "CustID_3628599@HMG.com", + "CustID_${appState.getAuthenticatedUser()!.patientId.toString()}@HMG.com", selectedPaymentMethod, - "1", - "Haroon Amjad", - "3628599", - AuthenticatedUser(outSa: 0, mobileNumber: "0593233758"), + appState.getAuthenticatedUser()!.patientType.toString(), + "${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}", + appState.getAuthenticatedUser()!.patientId.toString(), + appState.getAuthenticatedUser()!, browser!, widget.patientAppointmentHistoryResponseModel.isLiveCareAppointment ?? false, "2", @@ -429,9 +429,9 @@ class _AppointmentPaymentPageState extends State { //TODO: Need to pass dynamic params to the payment request instead of static values applePayInsertRequest.currency = "SAR"; - applePayInsertRequest.customerEmail = "CustID_3628599@HMG.com"; - applePayInsertRequest.customerID = "3628599"; - applePayInsertRequest.customerName = "Haroon Amjad"; + applePayInsertRequest.customerEmail = "CustID_${appState.getAuthenticatedUser()!.patientId.toString()}@HMG.com"; + applePayInsertRequest.customerID = appState.getAuthenticatedUser()!.patientId.toString(); + applePayInsertRequest.customerName = "${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}"; applePayInsertRequest.deviceToken = await Utils.getStringFromPrefs(CacheConst.pushToken); applePayInsertRequest.voipToken = await Utils.getStringFromPrefs(CacheConst.voipToken); @@ -439,7 +439,7 @@ class _AppointmentPaymentPageState extends State { applePayInsertRequest.projectID = widget.patientAppointmentHistoryResponseModel.projectID.toString(); applePayInsertRequest.serviceID = ServiceTypeEnum.appointmentPayment.getIdFromServiceEnum().toString(); applePayInsertRequest.channelID = 3; - applePayInsertRequest.patientID = "3628599"; + applePayInsertRequest.patientID = appState.getAuthenticatedUser()!.patientId.toString(); applePayInsertRequest.patientTypeID = 1; applePayInsertRequest.patientOutSA = 0; applePayInsertRequest.appointmentDate = widget.patientAppointmentHistoryResponseModel.appointmentDate; @@ -470,9 +470,9 @@ class _AppointmentPaymentPageState extends State { //TODO: Need to pass dynamic params to the Apple Pay instead of static values await payfortViewModel.applePayRequestInsert(applePayInsertRequest: applePayInsertRequest).then((value) { payfortViewModel.paymentWithApplePay( - customerName: "Haroon Amjad", + customerName: "${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}", // customerEmail: projectViewModel.authenticatedUserObject.user.emailAddress, - customerEmail: "CustID_3628599@HMG.com", + customerEmail: "CustID_${appState.getAuthenticatedUser()!.patientId.toString()}@HMG.com", orderDescription: "Appointment Payment", orderAmount: double.parse(myAppointmentsViewModel.patientAppointmentShareResponseModel!.patientShareWithTax!.toString()), merchantReference: transID, diff --git a/lib/presentation/appointments/my_appointments_page.dart b/lib/presentation/appointments/my_appointments_page.dart index 702f60d..0850641 100644 --- a/lib/presentation/appointments/my_appointments_page.dart +++ b/lib/presentation/appointments/my_appointments_page.dart @@ -6,6 +6,7 @@ import 'package:flutter_staggered_animations/flutter_staggered_animations.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/utils/size_utils.dart'; +import 'package:hmg_patient_app_new/core/utils/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/my_appointments/my_appointments_view_model.dart'; @@ -59,7 +60,7 @@ class _MyAppointmentsPageState extends State { tabs: [ CustomTabBarModel(null, "All Appt.".needTranslation), CustomTabBarModel(null, "Upcoming".needTranslation), - CustomTabBarModel(null, LocaleKeys.request.tr(context: context)), + CustomTabBarModel(null, "Completed".needTranslation), ], onTabChange: (index) { print(index); @@ -74,11 +75,11 @@ class _MyAppointmentsPageState extends State { ListView.separated( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), - itemCount: myAppointmentsVM.isMyAppointmentsLoading ? 5 : myAppointmentsVM.patientAppointmentsHistoryList.length, + itemCount: myAppointmentsVM.isMyAppointmentsLoading ? 5 : myAppointmentsVM.patientAppointmentsHistoryList.isNotEmpty ? myAppointmentsVM.patientAppointmentsHistoryList.length : 1, itemBuilder: (context, index) { return myAppointmentsVM.isMyAppointmentsLoading ? const MoviesShimmerWidget().paddingSymmetrical(24.h, 0.h) - : AnimationConfiguration.staggeredList( + : myAppointmentsVM.patientAppointmentsHistoryList.isNotEmpty ? AnimationConfiguration.staggeredList( position: index, duration: const Duration(milliseconds: 500), child: SlideAnimation( @@ -96,7 +97,7 @@ class _MyAppointmentsPageState extends State { ).paddingSymmetrical(24.h, 0.h), ), ), - ); + ) : Utils.getNoDataWidget(context); }, separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h), ), diff --git a/lib/presentation/appointments/widgets/appointment_card.dart b/lib/presentation/appointments/widgets/appointment_card.dart index 074c01a..51af492 100644 --- a/lib/presentation/appointments/widgets/appointment_card.dart +++ b/lib/presentation/appointments/widgets/appointment_card.dart @@ -13,7 +13,9 @@ import 'package:hmg_patient_app_new/features/my_appointments/utils/appointment_t import 'package:hmg_patient_app_new/presentation/appointments/appointment_details_page.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; +import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart'; +import 'package:smooth_corner/smooth_corner.dart'; class AppointmentCard extends StatefulWidget { AppointmentCard({super.key, required this.patientAppointmentHistoryResponseModel, required this.myAppointmentsViewModel}); @@ -38,7 +40,7 @@ class _AppointmentCardState extends State { ); }, child: Padding( - padding: EdgeInsets.all(16.h), + padding: EdgeInsets.all(14.h), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -123,77 +125,28 @@ class _AppointmentCardState extends State { fit: BoxFit.fill, ).circle(100), SizedBox(width: 16.h), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - widget.patientAppointmentHistoryResponseModel.doctorNameObj!.toText16(isBold: true), - SizedBox(height: 8.h), - Row( - children: [ - CustomButton( - text: widget.patientAppointmentHistoryResponseModel.clinicName!, - onPressed: () {}, - backgroundColor: AppColors.greyColor, - borderColor: AppColors.greyColor, - textColor: AppColors.blackColor, - fontSize: 10, - fontWeight: FontWeight.w500, - borderRadius: 8, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 30.h, - ), - SizedBox(width: 6.h), - CustomButton( - text: widget.patientAppointmentHistoryResponseModel.projectName!, - onPressed: () {}, - backgroundColor: AppColors.greyColor, - borderColor: AppColors.greyColor, - textColor: AppColors.blackColor, - fontSize: 10, - fontWeight: FontWeight.w500, - borderRadius: 8, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 30.h, - ), - ], - ), - SizedBox(height: 6.h), - Row( - children: [ - CustomButton( - icon: AppAssets.appointment_calendar_icon, - iconColor: AppColors.blackColor, - iconSize: 12.h, - text: DateUtil.formatDateToDate(DateUtil.convertStringToDate(widget.patientAppointmentHistoryResponseModel.appointmentDate), false), - onPressed: () {}, - backgroundColor: AppColors.greyColor, - borderColor: AppColors.greyColor, - textColor: AppColors.blackColor, - fontSize: 10, - fontWeight: FontWeight.w500, - borderRadius: 8, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 30.h, - ), - SizedBox(width: 6.h), - CustomButton( - icon: AppAssets.appointment_time_icon, - iconColor: AppColors.blackColor, - iconSize: 12.h, - text: DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(widget.patientAppointmentHistoryResponseModel.appointmentDate), false), - onPressed: () {}, - backgroundColor: AppColors.greyColor, - borderColor: AppColors.greyColor, - textColor: AppColors.blackColor, - fontSize: 10, - fontWeight: FontWeight.w500, - borderRadius: 8, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 30.h, - ), - ], - ) - ], + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + widget.patientAppointmentHistoryResponseModel.doctorNameObj!.toText16(isBold: true), + Wrap( + direction: Axis.horizontal, + spacing: 3.h, + runSpacing: -8.h, + children: [ + AppCustomChipWidget(labelText: widget.patientAppointmentHistoryResponseModel.clinicName!), + AppCustomChipWidget(labelText: widget.patientAppointmentHistoryResponseModel.projectName!), + AppCustomChipWidget( + icon: AppAssets.appointment_calendar_icon, + labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(widget.patientAppointmentHistoryResponseModel.appointmentDate), false)), + AppCustomChipWidget( + icon: AppAssets.appointment_time_icon, + labelText: DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(widget.patientAppointmentHistoryResponseModel.appointmentDate), false)), + ], + ), + ], + ), ), ], ), @@ -205,11 +158,14 @@ class _AppointmentCardState extends State { child: CustomButton( text: AppointmentType.getNextActionText(widget.patientAppointmentHistoryResponseModel.nextAction), onPressed: () { - Navigator.of(context).push( - FadePage( - page: AppointmentDetailsPage(patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel), - ), - ); + Navigator.of(context) + .push(FadePage( + page: AppointmentDetailsPage(patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel), + )) + .then((val) { + widget.myAppointmentsViewModel.initAppointmentsViewModel(); + widget.myAppointmentsViewModel.getPatientAppointments(true, false); + }); }, backgroundColor: AppointmentType.getNextActionButtonColor(widget.patientAppointmentHistoryResponseModel.nextAction).withOpacity(0.1), borderColor: AppointmentType.getNextActionButtonColor(widget.patientAppointmentHistoryResponseModel.nextAction).withOpacity(0.01), diff --git a/lib/presentation/appointments/widgets/appointment_doctor_card.dart b/lib/presentation/appointments/widgets/appointment_doctor_card.dart index 65a0fe8..801fdca 100644 --- a/lib/presentation/appointments/widgets/appointment_doctor_card.dart +++ b/lib/presentation/appointments/widgets/appointment_doctor_card.dart @@ -10,6 +10,7 @@ import 'package:hmg_patient_app_new/features/my_appointments/utils/appointment_t import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; +import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; class AppointmentDoctorCard extends StatelessWidget { AppointmentDoctorCard({super.key, required this.patientAppointmentHistoryResponseModel, required this.onRescheduleTap, required this.onCancelTap, required this.onAskDoctorTap}); @@ -28,7 +29,7 @@ class AppointmentDoctorCard extends StatelessWidget { hasShadow: true, ), child: Padding( - padding: EdgeInsets.all(16.h), + padding: EdgeInsets.all(14.h), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -42,77 +43,30 @@ class AppointmentDoctorCard extends StatelessWidget { fit: BoxFit.fill, ).circle(100), SizedBox(width: 16.h), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - patientAppointmentHistoryResponseModel.doctorNameObj!.toText16(isBold: true), - SizedBox(height: 8.h), - Row( - children: [ - CustomButton( - text: patientAppointmentHistoryResponseModel.clinicName!, - onPressed: () {}, - backgroundColor: AppColors.greyColor, - borderColor: AppColors.greyColor, - textColor: AppColors.blackColor, - fontSize: 10, - fontWeight: FontWeight.w500, - borderRadius: 8, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 30.h, - ), - SizedBox(width: 6.h), - CustomButton( - text: patientAppointmentHistoryResponseModel.projectName!, - onPressed: () {}, - backgroundColor: AppColors.greyColor, - borderColor: AppColors.greyColor, - textColor: AppColors.blackColor, - fontSize: 10, - fontWeight: FontWeight.w500, - borderRadius: 8, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 30.h, - ), - ], - ), - SizedBox(height: 6.h), - Row( - children: [ - CustomButton( - icon: AppAssets.appointment_calendar_icon, - iconColor: AppColors.blackColor, - iconSize: 12.h, - text: DateUtil.formatDateToDate(DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate), false), - onPressed: () {}, - backgroundColor: AppColors.greyColor, - borderColor: AppColors.greyColor, - textColor: AppColors.blackColor, - fontSize: 10, - fontWeight: FontWeight.w500, - borderRadius: 8, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 30.h, - ), - SizedBox(width: 6.h), - CustomButton( - icon: AppAssets.appointment_time_icon, - iconColor: AppColors.blackColor, - iconSize: 12.h, - text: DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate), false), - onPressed: () {}, - backgroundColor: AppColors.greyColor, - borderColor: AppColors.greyColor, - textColor: AppColors.blackColor, - fontSize: 10, - fontWeight: FontWeight.w500, - borderRadius: 8, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 30.h, - ), - ], - ) - ], + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + patientAppointmentHistoryResponseModel.doctorNameObj!.toText16(isBold: true), + Wrap( + direction: Axis.horizontal, + spacing: 3.h, + runSpacing: -8.h, + children: [ + AppCustomChipWidget(labelText: patientAppointmentHistoryResponseModel.clinicName!), + AppCustomChipWidget(labelText: patientAppointmentHistoryResponseModel.projectName!), + AppCustomChipWidget( + icon: AppAssets.doctor_calendar_icon, + labelText: + "${DateUtil.formatDateToDate(DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate), false)}, ${DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate), false)}"), + AppCustomChipWidget( + icon: AppAssets.rating_icon, + iconColor: AppColors.ratingColorYellow, + labelText: "Rating: ${patientAppointmentHistoryResponseModel.decimalDoctorRate}"), + ], + ), + ], + ), ), ], ), diff --git a/lib/presentation/authentication/saved_login_screen.dart b/lib/presentation/authentication/saved_login_screen.dart index 357daa6..57f115d 100644 --- a/lib/presentation/authentication/saved_login_screen.dart +++ b/lib/presentation/authentication/saved_login_screen.dart @@ -78,7 +78,7 @@ class _SavedLogin extends State { children: [ // Last login info - ("${LocaleKeys.lastloginBy.tr()} ${LoginTypeExtension.fromValue(appState.getSelectDeviceByImeiRespModelElement!.logInType!)!.displayName}") + ("${LocaleKeys.lastloginBy.tr()} ${LoginTypeExtension.fromValue(appState.getSelectDeviceByImeiRespModelElement!.logInType ?? 0)!.displayName}") .toText14(isBold: true, color: AppColors.greyTextColor), (appState.getSelectDeviceByImeiRespModelElement!.createdOn != null ? DateUtil.getFormattedDate(DateUtil.convertStringToDate(appState.getSelectDeviceByImeiRespModelElement!.createdOn!), "d MMMM, y at HH:mm") @@ -189,6 +189,7 @@ class _SavedLogin extends State { borderColor: AppColors.textColor, textColor: AppColors.textColor, icon: AppAssets.whatsapp, + iconColor: null, ), ), ], diff --git a/lib/presentation/home/landing_page.dart b/lib/presentation/home/landing_page.dart index 29bed41..9751987 100644 --- a/lib/presentation/home/landing_page.dart +++ b/lib/presentation/home/landing_page.dart @@ -288,7 +288,7 @@ class _LandingPageState extends State { scrollDirection: Axis.horizontal, itemCount: LandingPageData.getServiceCardsList.length, shrinkWrap: true, - padding: const EdgeInsets.only(left: 0, right: 8), + padding: EdgeInsets.only(left: 24.h, right: 24.h), itemBuilder: (context, index) { return AnimationConfiguration.staggeredList( position: index, @@ -306,7 +306,7 @@ class _LandingPageState extends State { ), ); }, - separatorBuilder: (BuildContext cxt, int index) => 0.width, + separatorBuilder: (BuildContext cxt, int index) => 8.width, ), ), ], diff --git a/lib/presentation/home/widgets/large_service_card.dart b/lib/presentation/home/widgets/large_service_card.dart index 8318798..8473eff 100644 --- a/lib/presentation/home/widgets/large_service_card.dart +++ b/lib/presentation/home/widgets/large_service_card.dart @@ -34,7 +34,7 @@ class LargeServiceCard extends StatelessWidget { borderRadius: 16, ), child: Padding( - padding: EdgeInsets.symmetric(horizontal: 8.h), + padding: EdgeInsets.symmetric(horizontal: 0.h), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, diff --git a/lib/presentation/insurance/widgets/patient_insurance_card.dart b/lib/presentation/insurance/widgets/patient_insurance_card.dart index 4906493..899016e 100644 --- a/lib/presentation/insurance/widgets/patient_insurance_card.dart +++ b/lib/presentation/insurance/widgets/patient_insurance_card.dart @@ -1,6 +1,8 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/cupertino.dart'; import 'package:hmg_patient_app_new/core/app_assets.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/utils/date_util.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; @@ -21,9 +23,11 @@ class PatientInsuranceCard extends StatelessWidget { bool isInsuranceExpired = false; late InsuranceViewModel insuranceViewModel; + late AppState appState; @override Widget build(BuildContext context) { + appState = getIt.get(); insuranceViewModel = Provider.of(context); return Container( width: double.infinity, @@ -42,7 +46,7 @@ class PatientInsuranceCard extends StatelessWidget { Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - "Haroon Amjad".toText18(isBold: true), + "${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}".toText18(isBold: true), "Policy: ${insuranceCardDetailsModel.insurancePolicyNo}".toText12(isBold: true, color: AppColors.lightGrayColor), ], ), @@ -118,9 +122,15 @@ class PatientInsuranceCard extends StatelessWidget { text: "${LocaleKeys.updateInsurance.tr(context: context)} ${LocaleKeys.updateInsuranceSubtitle.tr(context: context)}", onPressed: () { insuranceViewModel.setIsInsuranceUpdateDetailsLoading(true); - insuranceViewModel.getPatientInsuranceDetailsForUpdate(); + insuranceViewModel.getPatientInsuranceDetailsForUpdate( + appState.getAuthenticatedUser()!.patientId.toString(), appState.getAuthenticatedUser()!.patientIdentificationNo.toString()); showCommonBottomSheet(context, - child: PatientInsuranceCardUpdateCard(), callBackFunc: (str) {}, title: "", height: ResponsiveExtension.screenHeight * 0.42, isCloseButtonVisible: false, isFullScreen: false); + child: PatientInsuranceCardUpdateCard(), + callBackFunc: (str) {}, + title: "", + height: ResponsiveExtension.screenHeight * 0.42, + isCloseButtonVisible: false, + isFullScreen: false); }, backgroundColor: AppColors.bgGreenColor.withOpacity(0.20), borderColor: AppColors.bgGreenColor.withOpacity(0.0), diff --git a/lib/presentation/lab/search_lab_report.dart b/lib/presentation/lab/search_lab_report.dart index d513b35..e5b52e0 100644 --- a/lib/presentation/lab/search_lab_report.dart +++ b/lib/presentation/lab/search_lab_report.dart @@ -71,8 +71,9 @@ class _SearchLabResultsContentState extends State { controller: searchEditingController, isEnable: true, prefix: null, - autoFocus: true, + autoFocus: false, isBorderAllowed: false, + keyboardType: TextInputType.text, padding: EdgeInsets.symmetric( vertical: ResponsiveExtension(10).h, horizontal: ResponsiveExtension(15).h, diff --git a/lib/presentation/medical_file/medical_file_page.dart b/lib/presentation/medical_file/medical_file_page.dart index 032eaf9..d6cbd14 100644 --- a/lib/presentation/medical_file/medical_file_page.dart +++ b/lib/presentation/medical_file/medical_file_page.dart @@ -3,6 +3,8 @@ import 'dart:async'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; +import 'package:hmg_patient_app_new/core/app_state.dart'; +import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/utils/date_util.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; @@ -30,6 +32,7 @@ class MedicalFilePage extends StatefulWidget { class _MedicalFilePageState extends State { late InsuranceViewModel insuranceViewModel; + late AppState appState; int currentIndex = 0; @@ -44,6 +47,7 @@ class _MedicalFilePageState extends State { @override Widget build(BuildContext context) { insuranceViewModel = Provider.of(context); + appState = getIt.get(); return Scaffold( backgroundColor: AppColors.bgScaffoldColor, appBar: AppBar( @@ -84,7 +88,7 @@ class _MedicalFilePageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Image.asset( - AppAssets.male_img, + appState.getAuthenticatedUser()?.gender == 1 ? AppAssets.male_img : AppAssets.femaleImg, width: 56.h, height: 56.h, ), @@ -92,7 +96,7 @@ class _MedicalFilePageState extends State { Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - "Haroon Amjad".toText18(isBold: true), + "${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}".toText18(isBold: true), SizedBox(height: 4.h), Row( children: [ @@ -100,7 +104,7 @@ class _MedicalFilePageState extends State { icon: AppAssets.file_icon, iconColor: AppColors.blackColor, iconSize: 12.h, - text: "File no: 3628599", + text: "File no: ${appState.getAuthenticatedUser()!.patientId}", onPressed: () {}, backgroundColor: AppColors.greyColor, borderColor: AppColors.greyColor, @@ -136,7 +140,7 @@ class _MedicalFilePageState extends State { Row( children: [ CustomButton( - text: "30 Years Old", + text: "${appState.getAuthenticatedUser()!.age} Years Old", onPressed: () {}, backgroundColor: AppColors.greyColor, borderColor: AppColors.greyColor, @@ -152,7 +156,7 @@ class _MedicalFilePageState extends State { icon: AppAssets.blood_icon, iconColor: AppColors.primaryRedColor, iconSize: 13.h, - text: "Blood: A+", + text: "Blood: ${appState.getUserBloodGroup}", onPressed: () {}, backgroundColor: AppColors.greyColor, borderColor: AppColors.greyColor, diff --git a/lib/widgets/buttons/custom_button.dart b/lib/widgets/buttons/custom_button.dart index 5413cea..e1448dc 100644 --- a/lib/widgets/buttons/custom_button.dart +++ b/lib/widgets/buttons/custom_button.dart @@ -18,7 +18,7 @@ class CustomButton extends StatelessWidget { final String? fontFamily; final FontWeight fontWeight; final bool isDisabled; - final Color iconColor; + final Color? iconColor; final double height; final double iconSize; diff --git a/lib/widgets/chip/app_custom_chip_widget.dart b/lib/widgets/chip/app_custom_chip_widget.dart new file mode 100644 index 0000000..ee5dfc4 --- /dev/null +++ b/lib/widgets/chip/app_custom_chip_widget.dart @@ -0,0 +1,57 @@ +import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/core/app_assets.dart'; +import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; +import 'package:hmg_patient_app_new/core/utils/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/theme/colors.dart'; +import 'package:smooth_corner/smooth_corner.dart'; + +class AppCustomChipWidget extends StatelessWidget { + AppCustomChipWidget({ + super.key, + required this.labelText, + this.textColor = AppColors.textColor, + this.backgroundColor = AppColors.greyColor, + this.iconSize = 12, + this.icon = "", + this.iconColor = AppColors.textColor, + }); + + String? labelText; + Color? textColor; + Color? backgroundColor; + num iconSize; + String icon; + Color iconColor; + + @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, + ), + borderRadius: BorderRadius.circular(8.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: iconColor) : SizedBox.shrink(), + label: labelText!.toText10(weight: FontWeight.w500, letterSpacing: -0.64, color: textColor), + padding: EdgeInsets.all(0.0), + labelPadding: EdgeInsets.only(left: -4.h, right: 8.h), + backgroundColor: backgroundColor, + ) + : Chip( + label: labelText!.toText10(weight: FontWeight.w500, letterSpacing: -0.64, color: textColor), + padding: EdgeInsets.all(0.0), + backgroundColor: backgroundColor, + ), + ); + } +} diff --git a/lib/widgets/common_bottom_sheet.dart b/lib/widgets/common_bottom_sheet.dart index 25df532..11b7df8 100644 --- a/lib/widgets/common_bottom_sheet.dart +++ b/lib/widgets/common_bottom_sheet.dart @@ -7,7 +7,14 @@ import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; void showCommonBottomSheet(BuildContext context, - {required Widget child, Function(String?)? callBackFunc, String? title, required double height, bool isCloseButtonVisible = true, bool isFullScreen = true, bool isDismissible = true}) { + {required Widget child, + Function(String?)? callBackFunc, + String? title, + required double height, + bool isCloseButtonVisible = true, + bool isFullScreen = true, + bool isDismissible = true, + bool isSuccessDialog = false}) { showModalBottomSheet( sheetAnimationStyle: AnimationStyle( duration: Duration(milliseconds: 500), // Custom animation duration @@ -17,7 +24,7 @@ void showCommonBottomSheet(BuildContext context, isScrollControlled: true, showDragHandle: false, isDismissible: isDismissible, - backgroundColor: AppColors.scaffoldBgColor, + backgroundColor: isSuccessDialog ? AppColors.whiteColor : AppColors.scaffoldBgColor, builder: (BuildContext context) { return Container( height: height, @@ -30,9 +37,9 @@ void showCommonBottomSheet(BuildContext context, ), ); }).then((value) { - if(value != null) { - callBackFunc!(value); - } + if (value != null) { + callBackFunc!(value); + } }); } @@ -67,13 +74,18 @@ class ButtonSheetContent extends StatelessWidget { // Close button isCloseButtonVisible && isFullScreen ? Column(children: [ - SizedBox(height: 40.h,), - Padding( - padding: EdgeInsets.symmetric(horizontal: 16,), - child: Utils.buildSvgWithAssets(icon: AppAssets.closeBottomNav, width: 32, height: 32).onPress(() { - Navigator.of(context).pop(); - }), - )]) + SizedBox( + height: 40.h, + ), + Padding( + padding: EdgeInsets.symmetric( + horizontal: 16, + ), + child: Utils.buildSvgWithAssets(icon: AppAssets.closeBottomNav, width: 32, height: 32).onPress(() { + Navigator.of(context).pop(); + }), + ) + ]) : SizedBox(), isFullScreen diff --git a/lib/widgets/custom_tab_bar.dart b/lib/widgets/custom_tab_bar.dart index e43c004..870e85b 100644 --- a/lib/widgets/custom_tab_bar.dart +++ b/lib/widgets/custom_tab_bar.dart @@ -102,7 +102,7 @@ class _CustomTabBarState extends State { children: [ if (tabBar.image != null) Utils.buildSvgWithAssets(icon: tabBar.image!, height: 18, width: 18, iconColor: isSelected ? widget.activeTextColor : widget.inActiveTextColor), tabBar.title - .toText14(weight: isSelected ? FontWeight.w600 : FontWeight.w500, color: isSelected ? widget.activeTextColor : widget.inActiveTextColor, letterSpacing: isSelected ? -0.3 : -0.1), + .toText13(weight: isSelected ? FontWeight.w600 : FontWeight.w500, color: isSelected ? widget.activeTextColor : widget.inActiveTextColor, letterSpacing: isSelected ? -0.3 : -0.1), ], )).onPress(() { setState(() {