Symptoms checker doctor selection implemented

pull/188/head
haroon amjad 2 weeks ago
parent 5015747580
commit 305b3274c0

@ -36,6 +36,7 @@ abstract class ApiClient {
required Function(dynamic response, int statusCode) onSuccess,
required Function(String error, int statusCode) onFailure,
Map<String, dynamic>? queryParams,
Map<String, String> apiHeaders,
bool isAllowAny,
bool isExternal,
bool isRCService,
@ -366,6 +367,7 @@ class ApiClientImp implements ApiClient {
{required Function(dynamic response, int statusCode) onSuccess,
required Function(String error, int statusCode) onFailure,
Map<String, dynamic>? queryParams,
Map<String, String>? apiHeaders,
bool isAllowAny = false,
bool isExternal = false,
bool isRCService = false}) async {
@ -390,7 +392,7 @@ class ApiClientImp implements ApiClient {
if (await Utils.checkConnection(bypassConnectionCheck: true)) {
final response = await http.get(
Uri.parse(url.trim()),
headers: {'Content-Type': 'application/json', 'Accept': 'application/json'},
headers: apiHeaders ?? {'Content-Type': 'application/json', 'Accept': 'application/json'},
);
final int statusCode = response.statusCode;
// print("statusCode :$statusCode");

@ -683,7 +683,7 @@ const DASHBOARD = 'Services/Patients.svc/REST/PatientDashboard';
class ApiConsts {
static const maxSmallScreen = 660;
static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.uat;
static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.prod;
// static String baseUrl = 'https://uat.hmgwebservices.com/'; // HIS API URL UAT
@ -853,6 +853,7 @@ class ApiConsts {
static final String getSuggestions = '$symptomsCheckerApi/GetSuggestion';
static final String diagnosis = '$symptomsCheckerApi/GetDiagnosis';
static final String explain = '$symptomsCheckerApi/ExplainDiagnosisResult';
static final String getClinicFromCondition = '$symptomsCheckerApi/GetClinicsByCondition?condition=';
//E-REFERRAL SERVICES
static final getAllRelationshipTypes = "Services/Patients.svc/REST/GetAllRelationshipTypes";

@ -0,0 +1,25 @@
class GetClinicDetailsResponseModel {
String? category;
int? clinicID;
bool? isActive;
String? categoryAR;
GetClinicDetailsResponseModel(
{this.category, this.clinicID, this.isActive, this.categoryAR});
GetClinicDetailsResponseModel.fromJson(Map<String, dynamic> json) {
category = json['Category'];
clinicID = json['ClinicID'];
isActive = json['IsActive'];
categoryAR = json['CategoryAR'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['Category'] = this.category;
data['ClinicID'] = this.clinicID;
data['IsActive'] = this.isActive;
data['CategoryAR'] = this.categoryAR;
return data;
}
}

@ -6,6 +6,7 @@ import 'package:hmg_patient_app_new/core/api_consts.dart';
import 'package:hmg_patient_app_new/core/common_models/generic_api_model.dart';
import 'package:hmg_patient_app_new/core/exceptions/api_failure.dart';
import 'package:hmg_patient_app_new/features/symptoms_checker/models/resp_models/body_symptom_response_model.dart';
import 'package:hmg_patient_app_new/features/symptoms_checker/models/resp_models/get_clinic_details_response_model.dart';
import 'package:hmg_patient_app_new/features/symptoms_checker/models/resp_models/risk_and_suggestions_response_model.dart';
import 'package:hmg_patient_app_new/features/symptoms_checker/models/resp_models/symptoms_user_details_response_model.dart';
import 'package:hmg_patient_app_new/features/symptoms_checker/models/resp_models/triage_response_model.dart';
@ -50,6 +51,11 @@ abstract class SymptomsCheckerRepo {
required String userSessionToken,
required String sessionId,
});
Future<Either<Failure, GenericApiModel<List<GetClinicDetailsResponseModel>>>> getClinicDetails({
required String categoryName,
required String userSessionToken,
});
}
class SymptomsCheckerRepoImp implements SymptomsCheckerRepo {
@ -390,4 +396,57 @@ class SymptomsCheckerRepoImp implements SymptomsCheckerRepo {
return Left(UnknownFailure(e.toString()));
}
}
@override
Future<Either<Failure, GenericApiModel<List<GetClinicDetailsResponseModel>>>> getClinicDetails({
required String categoryName,
required String userSessionToken,
}) async {
Map<String, String> headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer $userSessionToken',
};
Map<String, dynamic> body = {};
try {
GenericApiModel<List<GetClinicDetailsResponseModel>>? apiResponse;
Failure? failure;
await apiClient.get(
"${ApiConsts.getClinicFromCondition}$categoryName",
apiHeaders: headers,
isExternal: true,
isAllowAny: true,
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType ?? ServerFailure(error);
},
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
final clinicDetails;
try {
final list = response['dataDetails'];
clinicDetails = list.map((item) => GetClinicDetailsResponseModel.fromJson(item as Map<String, dynamic>)).toList().cast<GetClinicDetailsResponseModel>();
apiResponse = GenericApiModel<List<GetClinicDetailsResponseModel>>(
messageStatus: messageStatus ?? 1,
statusCode: statusCode,
errorMessage: errorMessage,
data: clinicDetails,
);
} catch (e, stackTrace) {
loggerService.logError("Error parsing GetClinicsByCondition response: $e");
loggerService.logError("StackTrace: $stackTrace");
failure = DataParsingFailure(e.toString());
}
},
);
if (failure != null) return Left(failure!);
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
return Right(apiResponse!);
} catch (e, stackTrace) {
loggerService.logError("Exception in GetClinicsByCondition: $e");
loggerService.logError("StackTrace: $stackTrace");
return Left(UnknownFailure(e.toString()));
}
}
}

@ -6,6 +6,7 @@ import 'package:hmg_patient_app_new/core/enums.dart';
import 'package:hmg_patient_app_new/features/symptoms_checker/data/organ_mapping_data.dart';
import 'package:hmg_patient_app_new/features/symptoms_checker/models/organ_model.dart';
import 'package:hmg_patient_app_new/features/symptoms_checker/models/resp_models/body_symptom_response_model.dart';
import 'package:hmg_patient_app_new/features/symptoms_checker/models/resp_models/get_clinic_details_response_model.dart';
import 'package:hmg_patient_app_new/features/symptoms_checker/models/resp_models/risk_and_suggestions_response_model.dart';
import 'package:hmg_patient_app_new/features/symptoms_checker/models/resp_models/symptoms_user_details_response_model.dart';
import 'package:hmg_patient_app_new/features/symptoms_checker/models/resp_models/triage_response_model.dart';
@ -154,6 +155,8 @@ class SymptomsCheckerViewModel extends ChangeNotifier {
/// Get the number of triage questions answered
int get triageQuestionCount => _triageQuestionCount;
List<GetClinicDetailsResponseModel> clinicDetailsList = [];
/// Get choice index for a specific item
int? getTriageChoiceForItem(String itemId) {
return _selectedTriageChoicesByItemId[itemId];
@ -1069,6 +1072,43 @@ class SymptomsCheckerViewModel extends ChangeNotifier {
);
}
Future<void> getClinicConditionsFromCategory({
required String categoryName,
Function(dynamic)? onSuccess,
Function(String)? onError,
}) async {
clinicDetailsList.clear();
notifyListeners();
final result = await symptomsCheckerRepo.getClinicDetails(
categoryName: categoryName,
userSessionToken: currentSessionAuthToken,
);
result.fold(
(failure) async {
await errorHandlerService.handleError(failure: failure);
if (onError != null) {
onError(failure.toString());
}
},
(apiResponse) {
if (apiResponse.messageStatus == 1 && apiResponse.data != null) {
clinicDetailsList = apiResponse.data!;
notifyListeners();
if (onSuccess != null) {
onSuccess(apiResponse.data!);
}
} else {
notifyListeners();
if (onError != null) {
onError(apiResponse.errorMessage ?? 'Failed to fetch clinic details');
}
}
},
);
}
@override
void dispose() {
_tooltipTimer?.cancel();

@ -8,20 +8,32 @@ import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/extensions/route_extensions.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/book_appointments/book_appointments_view_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/get_clinic_list_response_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/appointment_via_region_viewmodel.dart';
import 'package:hmg_patient_app_new/features/symptoms_checker/models/resp_models/triage_response_model.dart';
import 'package:hmg_patient_app_new/features/symptoms_checker/symptoms_checker_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/appointments/widgets/faculity_selection/facility_type_selection_widget.dart';
import 'package:hmg_patient_app_new/presentation/appointments/widgets/region_bottomsheet/region_list_widget.dart';
import 'package:hmg_patient_app_new/presentation/symptoms_checker/widgets/condition_card.dart';
import 'package:hmg_patient_app_new/services/dialog_service.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
import 'package:provider/provider.dart';
import 'package:shimmer/shimmer.dart';
import '../appointments/widgets/hospital_bottom_sheet/hospital_bottom_sheet_body.dart';
class PossibleConditionsPage extends StatelessWidget {
const PossibleConditionsPage({super.key});
PossibleConditionsPage({super.key});
late SymptomsCheckerViewModel symptomsCheckerViewModel;
late BookAppointmentsViewModel bookAppointmentsViewModel;
late AppointmentViaRegionViewmodel regionalViewModel;
Widget _buildLoadingShimmer() {
return ListView.separated(
@ -80,8 +92,20 @@ class PossibleConditionsPage extends StatelessWidget {
condition: condition,
symptoms: symptoms,
onActionPressed: () {
dialogService.showErrorBottomSheet(
message: 'icd10 Code is ${condition.conditionDetails?.icd10Code}. We need to get the clinics mapped against this code.',
LoaderBottomSheet.showLoader();
symptomsCheckerViewModel.getClinicConditionsFromCategory(
categoryName: (condition.conditionDetails!.category!.name) ?? "Other",
onSuccess: (value) {
LoaderBottomSheet.hideLoader();
print(symptomsCheckerViewModel.clinicDetailsList.first.clinicID);
initiateBookAppointmentFlow(context);
},
onError: (err) {
LoaderBottomSheet.hideLoader();
dialogService.showErrorBottomSheet(
message: err.toString(),
);
},
);
},
);
@ -194,6 +218,9 @@ class PossibleConditionsPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
symptomsCheckerViewModel = context.read<SymptomsCheckerViewModel>();
bookAppointmentsViewModel = context.read<BookAppointmentsViewModel>();
regionalViewModel = context.read<AppointmentViaRegionViewmodel>();
return Scaffold(
backgroundColor: AppColors.bgScaffoldColor,
body: CollapsingListView(
@ -202,7 +229,6 @@ class PossibleConditionsPage extends StatelessWidget {
context: context,
onConfirm: () {
context.pop();
final SymptomsCheckerViewModel symptomsCheckerViewModel = context.read<SymptomsCheckerViewModel>();
symptomsCheckerViewModel.reset(); // Clear all symptoms checker data
final navigationService = getIt.get<NavigationService>();
// navigationService.replaceAllRoutesAndNavigateToLanding();
@ -230,4 +256,102 @@ class PossibleConditionsPage extends StatelessWidget {
),
);
}
initiateBookAppointmentFlow(BuildContext context) {
bookAppointmentsViewModel.getLocation();
bookAppointmentsViewModel.setSelectedClinic(GetClinicsListResponseModel(
clinicID: symptomsCheckerViewModel.clinicDetailsList.first.clinicID,
clinicDescription: symptomsCheckerViewModel.clinicDetailsList.first.category,
clinicDescriptionN: symptomsCheckerViewModel.clinicDetailsList.first.categoryAR,
));
bookAppointmentsViewModel.setIsDoctorsListLoading(true);
var bottomSheetType = RegionBottomSheetType.FOR_CLINIIC;
openRegionListBottomSheet(context, bottomSheetType);
}
getTitle(AppointmentViaRegionViewmodel data, BuildContext context) {
if (data.selectedRegionId == null) {
return LocaleKeys.selectRegion.tr(context: context).toText20(weight: FontWeight.w600);
} else {
return Transform.flip(
flipX: data.isArabic ? true : false,
child: Utils.buildSvgWithAssets(
icon: AppAssets.arrow_back,
iconColor: Color(0xff2B353E),
fit: BoxFit.contain,
),
).onPress(() {
data.handleBackPress();
});
}
}
void openRegionListBottomSheet(BuildContext context, RegionBottomSheetType type) {
bookAppointmentsViewModel.setProjectID(null);
regionalViewModel.flush();
regionalViewModel.setBottomSheetType(type);
// AppointmentViaRegionViewmodel? viewmodel = null;
showCommonBottomSheetWithoutHeight(context, title: "", titleWidget: Consumer<AppointmentViaRegionViewmodel>(builder: (_, data, __) => getTitle(data, context)), isDismissible: false,
child: Consumer<AppointmentViaRegionViewmodel>(builder: (context, data, __) {
return getRegionalSelectionWidget(data, context);
}), callBackFunc: () {});
}
Widget getRegionalSelectionWidget(AppointmentViaRegionViewmodel data, BuildContext context) {
if (data.bottomSheetState == AppointmentViaRegionState.REGION_SELECTION) {
return RegionBottomSheetBody();
}
if (data.bottomSheetState == AppointmentViaRegionState.TYPE_SELECTION) {
bookAppointmentsViewModel.resetFilterList();
return FacilityTypeSelectionWidget(
selectedRegion: data.selectedRegionId ?? "",
);
}
if (data.bottomSheetState == AppointmentViaRegionState.HOSPITAL_SELECTION) {
return HospitalBottomSheetBody(
searchText: data.searchController,
displayList: data.displayList,
onFacilityClicked: (value) {
data.setSelectedFacility(value);
data.getDisplayList();
},
onHospitalClicked: (hospital) {
regionalViewModel.setHospitalModel(hospital);
if (regionalViewModel.regionBottomSheetType == RegionBottomSheetType.FOR_REGION) {
regionalViewModel.setBottomSheetState(AppointmentViaRegionState.CLINIC_SELECTION);
regionalViewModel.handleLastStepForRegion();
} else if (regionalViewModel.regionBottomSheetType == RegionBottomSheetType.FOR_CLINIIC) {
regionalViewModel.setBottomSheetState(AppointmentViaRegionState.DOCTOR_SELECTION);
regionalViewModel.handleLastStepForClinic();
} else if (regionalViewModel.regionBottomSheetType == RegionBottomSheetType.REGION_FOR_DENTAL_AND_LASER) {
var appointmentsViewModel = Provider.of<BookAppointmentsViewModel>(context, listen: false);
regionalViewModel.setBottomSheetState(AppointmentViaRegionState.DOCTOR_SELECTION);
regionalViewModel.handleLastStepForClinicForDentalAndLaser(appointmentsViewModel.selectedClinic.clinicID ?? -1);
}
},
onHospitalSearch: (value) {
data.searchHospitals(value ?? "");
},
selectedFacility: data.selectedFacility,
hmcCount: data.hmcCount,
hmgCount: data.hmgCount,
);
}
if (data.bottomSheetState == AppointmentViaRegionState.DOCTOR_SELECTION) {
//if the region screen is opened for the dental clinic then the project id will be in the hospital list as the list is formed form the get project api
var id = "";
if (data.regionBottomSheetType == RegionBottomSheetType.REGION_FOR_DENTAL_AND_LASER) {
id = regionalViewModel.selectedHospital?.hospitalList.first.iD?.toString() ?? "";
} else {
id = regionalViewModel.selectedHospital?.patientDoctorAppointmentList?.first.projectID?.toString() ?? "";
}
bookAppointmentsViewModel.setProjectID(id);
return SizedBox.shrink();
} else {
return SizedBox.shrink();
}
return SizedBox.shrink();
}
}

Loading…
Cancel
Save