Ask Doctor implemented

pull/167/head
haroon amjad 2 weeks ago
parent 4188365e6d
commit 10a5a6f558

@ -0,0 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M1.25 11.5667C1.25 5.83838 6.09523 1.25 12 1.25C13.3843 1.25 14.7104 1.50218 15.9294 1.96211C16.2833 2.09563 16.4602 2.16239 16.4947 2.32216C16.5291 2.48194 16.3901 2.62094 16.1121 2.89895L14.71 4.30105C14.1098 4.90126 13.8469 5.61056 13.702 6.17788C13.6298 6.46083 13.5798 6.73917 13.5398 6.97064L13.4142 7.6505C13.3525 7.93768 13.2755 8.29627 13.2557 8.60763C13.2327 8.96869 13.2571 9.64265 13.8072 10.1928C14.3573 10.7429 15.0313 10.7673 15.3924 10.7443C15.7037 10.7245 16.0623 10.6475 16.3495 10.5858L17.0294 10.4602C17.2608 10.4202 17.5392 10.3702 17.8221 10.298C18.3894 10.1531 19.0987 9.89019 19.6989 9.28999L21.1613 7.82762C21.4366 7.55228 21.5743 7.41462 21.7337 7.44856C21.8931 7.4825 21.9598 7.65679 22.0934 8.00538C22.5179 9.11378 22.75 10.3129 22.75 11.5667C22.75 17.295 17.9048 21.8834 12 21.8834C11.3041 21.8843 10.6103 21.8199 9.92698 21.6916C9.68979 21.647 9.53909 21.6189 9.42696 21.6036C9.34334 21.5907 9.25931 21.6219 9.22775 21.6391C9.11322 21.6935 8.96068 21.7744 8.72714 21.8986C7.29542 22.66 5.62504 22.93 4.01396 22.6303C3.75381 22.5819 3.5384 22.4 3.44713 22.1517C3.35586 21.9033 3.40224 21.6252 3.56917 21.4199C4.03697 20.8445 4.35863 20.1513 4.50088 19.4052C4.53937 19.2 4.45227 18.9213 4.18451 18.6494C2.36972 16.8065 1.25 14.3144 1.25 11.5667ZM8 11C7.44772 11 7 11.4477 7 12C7 12.5523 7.44772 13 8 13H8.00897C8.56126 13 9.00897 12.5523 9.00897 12C9.00897 11.4477 8.56126 11 8.00897 11H8ZM11.9955 11C11.4432 11 10.9955 11.4477 10.9955 12C10.9955 12.5523 11.4432 13 11.9955 13H12.0045C12.5568 13 13.0045 12.5523 13.0045 12C13.0045 11.4477 12.5568 11 12.0045 11H11.9955Z" fill="#ED1C2B"/>
<path d="M19.7519 1.45375C19.5785 1.55385 19.4119 1.72053 19.0785 2.05388L15.7707 5.36171C15.2472 5.8852 15.1215 6.61984 14.9981 7.3412C14.9657 7.53049 14.9335 7.71887 14.8943 7.90228C14.7468 8.59223 14.673 8.9372 14.8679 9.13211C15.0628 9.32701 15.4078 9.25325 16.0977 9.10572C16.2811 9.0665 16.4695 9.03428 16.6588 9.00189C17.3802 8.87849 18.1148 8.75281 18.6383 8.22933L21.9461 4.92149C22.2795 4.58814 22.4461 4.42146 22.5463 4.24807C22.8179 3.77754 22.8179 3.19782 22.5463 2.72729C22.4461 2.5539 22.2795 2.38723 21.9461 2.05388C21.6128 1.72054 21.4461 1.55385 21.2727 1.45375C20.8022 1.18208 20.2225 1.18208 19.7519 1.45375Z" fill="#ED1C2B"/>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

@ -212,7 +212,7 @@ class ApiClientImp implements ApiClient {
final int statusCode = response.statusCode;
log("uri: ${Uri.parse(url.trim())}");
log("body: ${json.encode(body)}");
log("response.body: ${response.body}");
// log("response.body: ${response.body}");
if (statusCode < 200 || statusCode >= 400) {
onFailure('Error While Fetching data', statusCode, failureType: StatusCodeFailure("Error While Fetching data"));
logApiEndpointError(endPoint, 'Error While Fetching data', statusCode);

@ -680,7 +680,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

@ -309,6 +309,8 @@ class AppAssets {
static const String arLangIcon = '$svgBasePath/ar_lang_icon.svg';
static const String enLangIcon = '$svgBasePath/en_lang_icon.svg';
static const String doctorResponseIcon = '$svgBasePath/doctor_response_icon.svg';
// PNGS //
static const String hmgLogo = '$pngBasePath/hmg_logo.png';
static const String liveCareService = '$pngBasePath/livecare_service.png';

@ -4,6 +4,8 @@ import 'package:get_it/get_it.dart';
import 'package:hmg_patient_app_new/core/api/api_client.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/location_util.dart';
import 'package:hmg_patient_app_new/features/ask_doctor/ask_doctor_repo.dart';
import 'package:hmg_patient_app_new/features/ask_doctor/ask_doctor_view_model.dart';
import 'package:hmg_patient_app_new/features/authentication/authentication_repo.dart';
import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart';
import 'package:hmg_patient_app_new/features/blood_donation/blood_donation_repo.dart';
@ -166,6 +168,7 @@ class AppDependencies {
getIt.registerLazySingleton<MonthlyReportsRepo>(() => MonthlyReportsRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
getIt.registerLazySingleton<QrParkingRepo>(() => QrParkingRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
getIt.registerLazySingleton<NotificationsRepo>(() => NotificationsRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
getIt.registerLazySingleton<AskDoctorRepo>(() => AskDoctorRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
// ViewModels
// Global/shared VMs LazySingleton
@ -306,5 +309,7 @@ class AppDependencies {
),
);
getIt.registerLazySingleton<AskDoctorViewModel>(() => AskDoctorViewModel(askDoctorRepo: getIt(), errorHandlerService: getIt()));
}
}

@ -0,0 +1,128 @@
import 'package:dartz/dartz.dart';
import 'package:hmg_patient_app_new/core/api/api_client.dart';
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/core/utils/date_util.dart';
import 'package:hmg_patient_app_new/features/ask_doctor/models/ask_doctor_appointments_list.dart';
import 'package:hmg_patient_app_new/features/ask_doctor/models/doctor_response_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/ask_doctor_request_type_response_model.dart';
import 'package:hmg_patient_app_new/services/logger_service.dart';
abstract class AskDoctorRepo {
Future<Either<Failure, GenericApiModel<List<AskDoctorAppointmentHistoryList>>>> getAskDoctorAppointmentsList();
Future<Either<Failure, GenericApiModel<List<DoctorResponseModel>>>> getDoctorResponse({
required String fromDate,
});
}
class AskDoctorRepoImp implements AskDoctorRepo {
final ApiClient apiClient;
final LoggerService loggerService;
AskDoctorRepoImp({
required this.loggerService,
required this.apiClient,
});
@override
Future<Either<Failure, GenericApiModel<List<AskDoctorAppointmentHistoryList>>>> getAskDoctorAppointmentsList() async {
Map<String, dynamic> mapDevice = {
"Top": 25,
"beforeDays": 15,
"exludType": 4,
};
try {
GenericApiModel<List<AskDoctorAppointmentHistoryList>>? apiResponse;
Failure? failure;
await apiClient.post(
IS_ALLOW_ASK_DOCTOR,
body: mapDevice,
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
},
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
final list = response['PatientDoctorAppointmentResultList'];
final clinicsList = list.map((item) => AskDoctorAppointmentHistoryList.fromJson(item as Map<String, dynamic>)).toList().cast<AskDoctorAppointmentHistoryList>();
apiResponse = GenericApiModel<List<AskDoctorAppointmentHistoryList>>(
messageStatus: messageStatus,
statusCode: statusCode,
errorMessage: null,
data: clinicsList,
);
} 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()));
}
}
@override
Future<Either<Failure, GenericApiModel<List<DoctorResponseModel>>>> getDoctorResponse({
required String fromDate,
}) async {
Map<String, dynamic> mapDevice = {
"isDentalAllowedBackend": false,
"from": fromDate,
};
try {
GenericApiModel<List<DoctorResponseModel>>? apiResponse;
Failure? failure;
await apiClient.post(
GET_DOCTOR_RESPONSE,
body: mapDevice,
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
},
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
final list = response['List_DoctorResponse'];
if (list == null || list.isEmpty) {
// Return empty list if no responses
apiResponse = GenericApiModel<List<DoctorResponseModel>>(
messageStatus: messageStatus,
statusCode: statusCode,
errorMessage: null,
data: [],
);
return;
}
final doctorResponsesList = list
.map((item) => DoctorResponseModel.fromJson(item as Map<String, dynamic>))
.toList()
.cast<DoctorResponseModel>();
apiResponse = GenericApiModel<List<DoctorResponseModel>>(
messageStatus: messageStatus,
statusCode: statusCode,
errorMessage: null,
data: doctorResponsesList,
);
} 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) {
loggerService.logError("AskDoctorRepo.getDoctorResponse error: $e");
return Left(UnknownFailure(e.toString()));
}
}
}

@ -0,0 +1,93 @@
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/utils/date_util.dart';
import 'package:hmg_patient_app_new/features/ask_doctor/ask_doctor_repo.dart';
import 'package:hmg_patient_app_new/features/ask_doctor/models/ask_doctor_appointments_list.dart';
import 'package:hmg_patient_app_new/features/ask_doctor/models/doctor_response_model.dart';
import 'package:hmg_patient_app_new/services/error_handler_service.dart';
class AskDoctorViewModel extends ChangeNotifier {
final AskDoctorRepo askDoctorRepo;
final ErrorHandlerService errorHandlerService;
AskDoctorViewModel({
required this.askDoctorRepo,
required this.errorHandlerService,
});
bool isAskDoctorAppointmentsLoading = false;
bool isDoctorResponsesLoading = false;
List<AskDoctorAppointmentHistoryList> askDoctorAppointmentsList = [];
List<DoctorResponseModel> doctorResponsesList = [];
/// Initialize the view model
void initAskDoctorViewModel() {
askDoctorAppointmentsList.clear();
doctorResponsesList.clear();
isAskDoctorAppointmentsLoading = true;
getAskDoctorAppointmentsList();
notifyListeners();
}
Future<void> getAskDoctorAppointmentsList({Function(dynamic)? onSuccess, Function(String)? onError}) async {
final result = await askDoctorRepo.getAskDoctorAppointmentsList();
result.fold(
(failure) async => await errorHandlerService.handleError(failure: failure),
(apiResponse) {
if (apiResponse.messageStatus == 2) {
// dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
} else if (apiResponse.messageStatus == 1) {
askDoctorAppointmentsList = apiResponse.data!;
isAskDoctorAppointmentsLoading = false;
notifyListeners();
if (onSuccess != null) {
onSuccess(apiResponse);
}
}
},
);
}
/// Get doctor responses from a specific date
Future<void> getDoctorResponses({
String? fromDate,
Function(dynamic)? onSuccess,
Function(String)? onError,
}) async {
isDoctorResponsesLoading = true;
notifyListeners();
// If no date provided, use current date minus 30 days
final dateToUse = "${DateTime.now().year}-${DateTime.now().month}-${DateTime.now().day} ${DateTime.now().hour}:${DateTime.now().minute}:00";
final result = await askDoctorRepo.getDoctorResponse(fromDate: dateToUse);
result.fold(
(failure) async {
isDoctorResponsesLoading = false;
notifyListeners();
await errorHandlerService.handleError(failure: failure);
if (onError != null) {
onError(failure.toString());
}
},
(apiResponse) {
isDoctorResponsesLoading = false;
if (apiResponse.messageStatus == 2) {
notifyListeners();
if (onError != null) {
onError(apiResponse.errorMessage ?? "Unknown error");
}
} else if (apiResponse.messageStatus == 1) {
doctorResponsesList = apiResponse.data ?? [];
notifyListeners();
if (onSuccess != null) {
onSuccess(apiResponse);
}
}
},
);
}
}

@ -0,0 +1,200 @@
class AskDoctorAppointmentHistoryList {
String? setupID;
int? projectID;
int? appointmentNo;
String? appointmentDate;
bool? appointmentType;
String? bookDate;
bool? patientType;
int? patientID;
int? clinicID;
int? doctorID;
String? endDate;
String? startTime;
String? endTime;
bool? status;
bool? visitType;
bool? isReminderActivated;
int? companyID;
String? bookedOn;
String? confirmedOn;
String? arrivedOn;
String? editedOn;
int? appointmentDays;
int? isActive;
int? actualDoctorRate;
String? clinicName;
String? date;
num? decimalDoctorRate;
String? doctorCases;
String? doctorImageURL;
String? doctorInfo;
String? doctorName;
num? doctorRate;
num? doctorStarsRate;
String? doctorTitle;
int? gender;
String? genderDescription;
bool? isActiveDoctorProfile;
bool? isAppointmentAllowed;
bool? isDoctorAllowVedioCall;
bool? isLiveCareClinic;
String? nationalityFlagURL;
String? nationalityID;
String? nationalityName;
int? noOfPatientsRate;
String? projectName;
String? qR;
List<String>? speciality;
AskDoctorAppointmentHistoryList(
{this.setupID,
this.projectID,
this.appointmentNo,
this.appointmentDate,
this.appointmentType,
this.bookDate,
this.patientType,
this.patientID,
this.clinicID,
this.doctorID,
this.endDate,
this.startTime,
this.endTime,
this.status,
this.visitType,
this.isReminderActivated,
this.companyID,
this.bookedOn,
this.confirmedOn,
this.arrivedOn,
this.editedOn,
this.appointmentDays,
this.isActive,
this.actualDoctorRate,
this.clinicName,
this.date,
this.decimalDoctorRate,
this.doctorCases,
this.doctorImageURL,
this.doctorInfo,
this.doctorName,
this.doctorRate,
this.doctorStarsRate,
this.doctorTitle,
this.gender,
this.genderDescription,
this.isActiveDoctorProfile,
this.isAppointmentAllowed,
this.isDoctorAllowVedioCall,
this.isLiveCareClinic,
this.nationalityFlagURL,
this.nationalityID,
this.nationalityName,
this.noOfPatientsRate,
this.projectName,
this.qR,
this.speciality});
AskDoctorAppointmentHistoryList.fromJson(Map<String, dynamic> json) {
setupID = json['SetupID'];
projectID = json['ProjectID'];
appointmentNo = json['AppointmentNo'];
appointmentDate = json['AppointmentDate'];
appointmentType = json['AppointmentType'];
bookDate = json['BookDate'];
patientType = json['PatientType'];
patientID = json['PatientID'];
clinicID = json['ClinicID'];
doctorID = json['DoctorID'];
endDate = json['EndDate'];
startTime = json['StartTime'];
endTime = json['EndTime'];
status = json['Status'];
visitType = json['VisitType'];
isReminderActivated = json['IsReminderActivated'];
companyID = json['CompanyID'];
bookedOn = json['BookedOn'];
confirmedOn = json['ConfirmedOn'];
arrivedOn = json['ArrivedOn'];
editedOn = json['EditedOn'];
appointmentDays = json['AppointmentDays'];
isActive = json['IsActive'];
actualDoctorRate = json['ActualDoctorRate'];
clinicName = json['ClinicName'];
date = json['Date'];
decimalDoctorRate = json['DecimalDoctorRate'];
doctorCases = json['DoctorCases'];
doctorImageURL = json['DoctorImageURL'];
doctorInfo = json['DoctorInfo'];
doctorName = json['DoctorName'];
doctorRate = json['DoctorRate'];
doctorStarsRate = json['DoctorStarsRate'];
doctorTitle = json['DoctorTitle'];
gender = json['Gender'];
genderDescription = json['GenderDescription'];
isActiveDoctorProfile = json['IsActiveDoctorProfile'];
isAppointmentAllowed = json['IsAppointmentAllowed'];
isDoctorAllowVedioCall = json['IsDoctorAllowVedioCall'];
isLiveCareClinic = json['IsLiveCareClinic'];
nationalityFlagURL = json['NationalityFlagURL'];
nationalityID = json['NationalityID'];
nationalityName = json['NationalityName'];
noOfPatientsRate = json['NoOfPatientsRate'];
projectName = json['ProjectName'];
qR = json['QR'];
speciality = json['Speciality'].cast<String>();
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['SetupID'] = this.setupID;
data['ProjectID'] = this.projectID;
data['AppointmentNo'] = this.appointmentNo;
data['AppointmentDate'] = this.appointmentDate;
data['AppointmentType'] = this.appointmentType;
data['BookDate'] = this.bookDate;
data['PatientType'] = this.patientType;
data['PatientID'] = this.patientID;
data['ClinicID'] = this.clinicID;
data['DoctorID'] = this.doctorID;
data['EndDate'] = this.endDate;
data['StartTime'] = this.startTime;
data['EndTime'] = this.endTime;
data['Status'] = this.status;
data['VisitType'] = this.visitType;
data['IsReminderActivated'] = this.isReminderActivated;
data['CompanyID'] = this.companyID;
data['BookedOn'] = this.bookedOn;
data['ConfirmedOn'] = this.confirmedOn;
data['ArrivedOn'] = this.arrivedOn;
data['EditedOn'] = this.editedOn;
data['AppointmentDays'] = this.appointmentDays;
data['IsActive'] = this.isActive;
data['ActualDoctorRate'] = this.actualDoctorRate;
data['ClinicName'] = this.clinicName;
data['Date'] = this.date;
data['DecimalDoctorRate'] = this.decimalDoctorRate;
data['DoctorCases'] = this.doctorCases;
data['DoctorImageURL'] = this.doctorImageURL;
data['DoctorInfo'] = this.doctorInfo;
data['DoctorName'] = this.doctorName;
data['DoctorRate'] = this.doctorRate;
data['DoctorStarsRate'] = this.doctorStarsRate;
data['DoctorTitle'] = this.doctorTitle;
data['Gender'] = this.gender;
data['GenderDescription'] = this.genderDescription;
data['IsActiveDoctorProfile'] = this.isActiveDoctorProfile;
data['IsAppointmentAllowed'] = this.isAppointmentAllowed;
data['IsDoctorAllowVedioCall'] = this.isDoctorAllowVedioCall;
data['IsLiveCareClinic'] = this.isLiveCareClinic;
data['NationalityFlagURL'] = this.nationalityFlagURL;
data['NationalityID'] = this.nationalityID;
data['NationalityName'] = this.nationalityName;
data['NoOfPatientsRate'] = this.noOfPatientsRate;
data['ProjectName'] = this.projectName;
data['QR'] = this.qR;
data['Speciality'] = this.speciality;
return data;
}
}

@ -0,0 +1,180 @@
class DoctorResponseModel {
int? projectID;
int? transactionNo;
int? patientID;
int? doctorID;
int? requestType;
String? requestTypeDescription;
dynamic requestTypeDescriptionN;
int? status;
String? remarks;
String? createdOn;
int? readStatus;
String? doctorResponse;
dynamic clinicID;
dynamic clinicName;
int? createdBy;
String? doctorName;
dynamic infoStatusDescription;
bool? isDoctorRespond;
bool? isPatientRead;
dynamic memberName;
dynamic memberNameN;
dynamic patientDateofBirth;
dynamic patientGender;
dynamic patientMobileNumber;
dynamic patientName;
dynamic patientNameN;
dynamic projectName;
dynamic statusDescription;
List<Transactions>? transactions;
DoctorResponseModel(
{this.projectID,
this.transactionNo,
this.patientID,
this.doctorID,
this.requestType,
this.requestTypeDescription,
this.requestTypeDescriptionN,
this.status,
this.remarks,
this.createdOn,
this.readStatus,
this.doctorResponse,
this.clinicID,
this.clinicName,
this.createdBy,
this.doctorName,
this.infoStatusDescription,
this.isDoctorRespond,
this.isPatientRead,
this.memberName,
this.memberNameN,
this.patientDateofBirth,
this.patientGender,
this.patientMobileNumber,
this.patientName,
this.patientNameN,
this.projectName,
this.statusDescription,
this.transactions});
DoctorResponseModel.fromJson(Map<String, dynamic> json) {
projectID = json['ProjectID'];
transactionNo = json['TransactionNo'];
patientID = json['PatientID'];
doctorID = json['DoctorID'];
requestType = json['RequestType'];
requestTypeDescription = json['RequestTypeDescription'];
requestTypeDescriptionN = json['RequestTypeDescriptionN'];
status = json['Status'];
remarks = json['Remarks'];
createdOn = json['CreatedOn'];
readStatus = json['ReadStatus'];
doctorResponse = json['DoctorResponse'];
clinicID = json['ClinicID'];
clinicName = json['ClinicName'];
createdBy = json['CreatedBy'];
doctorName = json['DoctorName'];
infoStatusDescription = json['InfoStatusDescription'];
isDoctorRespond = json['IsDoctorRespond'];
isPatientRead = json['IsPatientRead'];
memberName = json['MemberName'];
memberNameN = json['MemberNameN'];
patientDateofBirth = json['PatientDateofBirth'];
patientGender = json['PatientGender'];
patientMobileNumber = json['PatientMobileNumber'];
patientName = json['PatientName'];
patientNameN = json['PatientNameN'];
projectName = json['ProjectName'];
statusDescription = json['StatusDescription'];
if (json['Transactions'] != null) {
transactions = <Transactions>[];
json['Transactions'].forEach((v) {
transactions!.add(new Transactions.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['ProjectID'] = this.projectID;
data['TransactionNo'] = this.transactionNo;
data['PatientID'] = this.patientID;
data['DoctorID'] = this.doctorID;
data['RequestType'] = this.requestType;
data['RequestTypeDescription'] = this.requestTypeDescription;
data['RequestTypeDescriptionN'] = this.requestTypeDescriptionN;
data['Status'] = this.status;
data['Remarks'] = this.remarks;
data['CreatedOn'] = this.createdOn;
data['ReadStatus'] = this.readStatus;
data['DoctorResponse'] = this.doctorResponse;
data['ClinicID'] = this.clinicID;
data['ClinicName'] = this.clinicName;
data['CreatedBy'] = this.createdBy;
data['DoctorName'] = this.doctorName;
data['InfoStatusDescription'] = this.infoStatusDescription;
data['IsDoctorRespond'] = this.isDoctorRespond;
data['IsPatientRead'] = this.isPatientRead;
data['MemberName'] = this.memberName;
data['MemberNameN'] = this.memberNameN;
data['PatientDateofBirth'] = this.patientDateofBirth;
data['PatientGender'] = this.patientGender;
data['PatientMobileNumber'] = this.patientMobileNumber;
data['PatientName'] = this.patientName;
data['PatientNameN'] = this.patientNameN;
data['ProjectName'] = this.projectName;
data['StatusDescription'] = this.statusDescription;
if (this.transactions != null) {
data['Transactions'] = this.transactions!.map((v) => v.toJson()).toList();
}
return data;
}
}
class Transactions {
int? lineItemNo;
String? doctorResponse;
int? infoEnteredBy;
String? infoEnteredOn;
String? createdOn;
int? infoStatus;
String? infoStatusDescription;
dynamic infoStatusDescriptionN;
Transactions(
{this.lineItemNo,
this.doctorResponse,
this.infoEnteredBy,
this.infoEnteredOn,
this.createdOn,
this.infoStatus,
this.infoStatusDescription,
this.infoStatusDescriptionN});
Transactions.fromJson(Map<String, dynamic> json) {
lineItemNo = json['LineItemNo'];
doctorResponse = json['DoctorResponse'];
infoEnteredBy = json['InfoEnteredBy'];
infoEnteredOn = json['InfoEnteredOn'];
createdOn = json['CreatedOn'];
infoStatus = json['InfoStatus'];
infoStatusDescription = json['InfoStatusDescription'];
infoStatusDescriptionN = json['InfoStatusDescriptionN'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['LineItemNo'] = this.lineItemNo;
data['DoctorResponse'] = this.doctorResponse;
data['InfoEnteredBy'] = this.infoEnteredBy;
data['InfoEnteredOn'] = this.infoEnteredOn;
data['CreatedOn'] = this.createdOn;
data['InfoStatus'] = this.infoStatus;
data['InfoStatusDescription'] = this.infoStatusDescription;
data['InfoStatusDescriptionN'] = this.infoStatusDescriptionN;
return data;
}
}

@ -8,6 +8,7 @@ import 'package:flutter/services.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/features/ask_doctor/ask_doctor_view_model.dart';
import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart';
import 'package:hmg_patient_app_new/features/blood_donation/blood_donation_view_model.dart';
import 'package:hmg_patient_app_new/features/active_prescriptions/active_prescriptions_view_model.dart';
@ -197,6 +198,9 @@ void main() async {
),
ChangeNotifierProvider<TermsConditionsViewModel>(
create: (_) => getIt.get<TermsConditionsViewModel>(),
),
ChangeNotifierProvider<AskDoctorViewModel>(
create: (_) => getIt.get<AskDoctorViewModel>(),
)
], child: MyApp()),
),

@ -0,0 +1,104 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_staggered_animations/flutter_staggered_animations.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/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/ask_doctor/ask_doctor_view_model.dart';
import 'package:hmg_patient_app_new/features/medical_file/models/patient_sickleave_response_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/appointments/widgets/appointment_card.dart';
import 'package:hmg_patient_app_new/presentation/ask_doctor/doctor_response_page.dart';
import 'package:hmg_patient_app_new/presentation/ask_doctor/widgets/ask_doctor_appointment_card.dart';
import 'package:hmg_patient_app_new/presentation/medical_file/widgets/patient_sick_leave_card.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/buttons/custom_button.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:provider/provider.dart';
class AskDoctorPage extends StatefulWidget {
const AskDoctorPage({super.key});
@override
State<AskDoctorPage> createState() => _AskDoctorPageState();
}
class _AskDoctorPageState extends State<AskDoctorPage> {
late MyAppointmentsViewModel myAppointmentsViewModel;
@override
Widget build(BuildContext context) {
myAppointmentsViewModel = Provider.of<MyAppointmentsViewModel>(context, listen: false);
return Scaffold(
backgroundColor: AppColors.bgScaffoldColor,
body: Consumer<AskDoctorViewModel>(
builder: (context, askDoctorVM, child) {
return CollapsingListView(
title: LocaleKeys.askDoctor.tr(context: context),
doctorResponse: () {
askDoctorVM.getDoctorResponses();
Navigator.of(context).push(
CustomPageRoute(
page: DoctorResponsePage(),
),
);
},
child: SingleChildScrollView(
child: Column(children: [
SizedBox(height: 16.h),
ListView.builder(
padding: EdgeInsets.only(top: 8.h),
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: askDoctorVM.isAskDoctorAppointmentsLoading
? 4
: askDoctorVM.askDoctorAppointmentsList.isNotEmpty
? askDoctorVM.askDoctorAppointmentsList.length
: 1,
itemBuilder: (context, index) {
return askDoctorVM.isAskDoctorAppointmentsLoading
? Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true),
child: PatientSickLeaveCard(
patientSickLeavesResponseModel: PatientSickLeavesResponseModel(),
isLoading: true,
)).paddingSymmetrical(0.w, 12.h)
: askDoctorVM.askDoctorAppointmentsList.isNotEmpty
? AnimationConfiguration.staggeredList(
position: index,
duration: const Duration(milliseconds: 500),
child: SlideAnimation(
verticalOffset: 100.0,
child: FadeInAnimation(
child: AnimatedContainer(
duration: Duration(milliseconds: 300),
curve: Curves.easeInOut,
margin: EdgeInsets.symmetric(vertical: 8.h),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 20.h, hasShadow: true),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AskDoctorAppointmentCard(
askDoctorAppointmentHistoryList: askDoctorVM.askDoctorAppointmentsList[index],
myAppointmentsViewModel: myAppointmentsViewModel,
)
],
),
),
),
),
)
: Utils.getNoDataWidget(context, noDataText: LocaleKeys.noAppointmentsYet.tr(context: context));
},
).paddingSymmetrical(24.h, 0.h),
SizedBox(height: 24.h),
]),
),
);
},
),
);
}
}

@ -0,0 +1,157 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
import 'package:hmg_patient_app_new/core/app_assets.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/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/ask_doctor/ask_doctor_view_model.dart';
import 'package:hmg_patient_app_new/features/medical_file/models/patient_sickleave_response_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/appointments/widgets/appointment_card.dart';
import 'package:hmg_patient_app_new/presentation/ask_doctor/widgets/ask_doctor_appointment_card.dart';
import 'package:hmg_patient_app_new/presentation/ask_doctor/widgets/doctor_response_transactions.dart';
import 'package:hmg_patient_app_new/presentation/medical_file/widgets/patient_sick_leave_card.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/buttons/custom_button.dart';
import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart';
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
import 'package:provider/provider.dart';
class DoctorResponsePage extends StatefulWidget {
const DoctorResponsePage({super.key});
@override
State<DoctorResponsePage> createState() => _DoctorResponsePageState();
}
class _DoctorResponsePageState extends State<DoctorResponsePage> {
late MyAppointmentsViewModel myAppointmentsViewModel;
@override
Widget build(BuildContext context) {
myAppointmentsViewModel = Provider.of<MyAppointmentsViewModel>(context, listen: false);
return Scaffold(
backgroundColor: AppColors.bgScaffoldColor,
body: CollapsingListView(
title: LocaleKeys.doctorResponses.tr(context: context),
child: SingleChildScrollView(
child: Column(
children: [
SizedBox(height: 16.h),
Consumer<AskDoctorViewModel>(builder: (context, askDoctorVM, child) {
return ListView.builder(
padding: EdgeInsets.zero,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: askDoctorVM.isDoctorResponsesLoading
? 4
: askDoctorVM.doctorResponsesList.isNotEmpty
? askDoctorVM.doctorResponsesList.length
: 1,
itemBuilder: (context, index) {
return askDoctorVM.isDoctorResponsesLoading
? Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true),
child: PatientSickLeaveCard(
patientSickLeavesResponseModel: PatientSickLeavesResponseModel(),
isLoading: true,
)).paddingSymmetrical(0.w, 12.h)
: askDoctorVM.doctorResponsesList.isNotEmpty
? AnimationConfiguration.staggeredList(
position: index,
duration: const Duration(milliseconds: 500),
child: SlideAnimation(
verticalOffset: 100.0,
child: FadeInAnimation(
child: AnimatedContainer(
duration: Duration(milliseconds: 300),
curve: Curves.easeInOut,
margin: EdgeInsets.symmetric(vertical: 8.h),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 20.h, hasShadow: true),
child: Padding(
padding: EdgeInsets.all(16.w),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
askDoctorVM.doctorResponsesList[index].requestTypeDescription!.toText18(isBold: true),
SizedBox(height: 24.h),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image.network(
"https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png",
width: 50.w,
height: 50.h,
fit: BoxFit.cover,
).circle(100.r),
],
),
SizedBox(width: 16.h),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
askDoctorVM.doctorResponsesList[index].doctorName!.toText16(isBold: true, maxlines: 1),
SizedBox(height: 8.h),
Wrap(
direction: Axis.horizontal,
spacing: 3.h,
runSpacing: 4.h,
children: [
AppCustomChipWidget(
labelText: (askDoctorVM.doctorResponsesList[index].clinicName ?? "").length > 15
? '${askDoctorVM.doctorResponsesList[index].clinicName!.substring(0, 12)}...'
: askDoctorVM.doctorResponsesList[index].clinicName ?? "",
),
AppCustomChipWidget(
labelText: (askDoctorVM.doctorResponsesList[index].projectName ?? "").length > 15
? '${askDoctorVM.doctorResponsesList[index].projectName!.substring(0, 12)}...'
: askDoctorVM.doctorResponsesList[index].projectName ?? ""),
AppCustomChipWidget(
labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: 6.w),
icon: AppAssets.appointment_calendar_icon,
labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(askDoctorVM.doctorResponsesList[index].createdOn), false),
),
],
),
],
),
),
],
),
],
),
),
).onPress(() {
showCommonBottomSheetWithoutHeight(
context,
title: askDoctorVM.doctorResponsesList[index].requestTypeDescription!,
child: DoctorResponseTransactions(doctorResponseModel: askDoctorVM.doctorResponsesList[index],),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
}),
),
),
)
: Utils.getNoDataWidget(context, noDataText: LocaleKeys.noDataAvailable.tr(context: context));
},
).paddingSymmetrical(24.h, 0.h);
}),
SizedBox(height: 24.h),
],
),
),
),
);
}
}

@ -0,0 +1,205 @@
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/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/ask_doctor/models/ask_doctor_appointments_list.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/patient_appointment_history_response_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/appointments/widgets/ask_doctor_request_type_select.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/common_bottom_sheet.dart';
import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
class AskDoctorAppointmentCard extends StatelessWidget {
final AskDoctorAppointmentHistoryList askDoctorAppointmentHistoryList;
final MyAppointmentsViewModel myAppointmentsViewModel;
const AskDoctorAppointmentCard({super.key, required this.askDoctorAppointmentHistoryList, required this.myAppointmentsViewModel});
@override
Widget build(BuildContext context) {
final appState = getIt.get<AppState>();
return Padding(
padding: EdgeInsets.all(14.h),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildHeader(context, appState),
SizedBox(height: 16.h),
_buildDoctorRow(context),
SizedBox(height: 16.h),
_buildActionArea(context, appState),
],
),
);
}
Widget _buildHeader(BuildContext context, AppState appState) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(child: _buildChips(context, appState)),
],
);
}
Widget _buildChips(BuildContext context, AppState appState) {
return Wrap(
alignment: WrapAlignment.start,
direction: Axis.horizontal,
spacing: 6.w,
runSpacing: 6.h,
children: [
AppCustomChipWidget(
icon: AppAssets.walkin_appointment_icon,
iconColor: AppColors.textColor,
labelText: LocaleKeys.walkin.tr(context: context),
backgroundColor: AppColors.greyColor,
textColor: AppColors.textColor,
),
AppCustomChipWidget(
labelText: LocaleKeys.outPatient.tr(context: context),
backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.1),
textColor: AppColors.primaryRedColor,
),
AppCustomChipWidget(
labelText: LocaleKeys.booked.tr(context: context),
backgroundColor: AppColors.successColor.withValues(alpha: 0.1),
textColor: AppColors.successColor,
),
],
);
}
Widget _buildDoctorRow(BuildContext context) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image.network(
askDoctorAppointmentHistoryList.doctorImageURL!,
width: 63.h,
height: 63.h,
fit: BoxFit.cover,
).circle(100.r),
Transform.translate(
offset: Offset(0.0, -20.h),
child: Container(
width: 40.w,
height: 40.h,
decoration: BoxDecoration(
color: AppColors.whiteColor,
shape: BoxShape.circle, // Makes the container circular
border: Border.all(
color: AppColors.scaffoldBgColor, // Color of the border
width: 1.5.w, // Width of the border
),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Utils.buildSvgWithAssets(icon: AppAssets.rating_icon, width: 15.w, height: 15.h),
SizedBox(height: 2.h),
"${askDoctorAppointmentHistoryList.decimalDoctorRate}".toText11(isBold: true, color: AppColors.textColor),
],
),
).circle(100),
),
],
),
SizedBox(width: 16.h),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
("${askDoctorAppointmentHistoryList.doctorTitle} ${askDoctorAppointmentHistoryList.doctorName!}").toText16(isBold: true, maxlines: 1),
SizedBox(height: 8.h),
Wrap(
direction: Axis.horizontal,
spacing: 3.h,
runSpacing: 4.h,
children: [
AppCustomChipWidget(
labelText:
askDoctorAppointmentHistoryList.clinicName!.length > 15 ? '${askDoctorAppointmentHistoryList.clinicName!.substring(0, 12)}...' : askDoctorAppointmentHistoryList.clinicName!,
),
AppCustomChipWidget(
labelText: askDoctorAppointmentHistoryList.projectName!.length > 15
? '${askDoctorAppointmentHistoryList.projectName!.substring(0, 12)}...'
: askDoctorAppointmentHistoryList.projectName!),
AppCustomChipWidget(
labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: 6.w),
icon: AppAssets.appointment_calendar_icon,
labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(askDoctorAppointmentHistoryList.appointmentDate), false),
),
],
),
],
),
),
],
);
}
Widget _buildActionArea(BuildContext context, AppState appState) {
return CustomButton(
text: LocaleKeys.askDoctor.tr(context: context),
onPressed: () async {
LoaderBottomSheet.showLoader(loadingText: LocaleKeys.checkingDoctorAvailability.tr(context: context));
await myAppointmentsViewModel.isDoctorAvailable(
projectID: askDoctorAppointmentHistoryList.projectID!,
doctorId: askDoctorAppointmentHistoryList.doctorID!,
clinicId: askDoctorAppointmentHistoryList.clinicID!,
onSuccess: (value) async {
if (value) {
await myAppointmentsViewModel.getAskDoctorRequestTypes(onSuccess: (val) {
LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight(
context,
title: LocaleKeys.askDoctor.tr(context: context),
child: AskDoctorRequestTypeSelect(
askDoctorRequestTypeList: myAppointmentsViewModel.askDoctorRequestTypeList,
myAppointmentsViewModel: myAppointmentsViewModel,
patientAppointmentHistoryResponseModel: PatientAppointmentHistoryResponseModel()
// myAppointmentsVM.patientAppointmentsHistoryList[index],
),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
});
} else {
LoaderBottomSheet.hideLoader();
}
},
onError: (_) {
LoaderBottomSheet.hideLoader();
},
);
},
backgroundColor: AppColors.secondaryLightRedColor,
borderColor: AppColors.secondaryLightRedColor,
textColor: AppColors.primaryRedColor,
fontSize: 14.f,
fontWeight: FontWeight.w500,
borderRadius: 12.r,
padding: EdgeInsets.symmetric(horizontal: 10.w),
// height: isTablet || isFoldable ? 46.h : 40.h,
height: 40.h,
icon: AppAssets.ask_doctor_icon,
iconColor: AppColors.primaryRedColor,
iconSize: 16.h,
);
}
}

@ -0,0 +1,131 @@
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/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/ask_doctor/models/doctor_response_model.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 DoctorResponseTransactions extends StatelessWidget {
const DoctorResponseTransactions({super.key, required this.doctorResponseModel});
final DoctorResponseModel doctorResponseModel;
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image.network(
"https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png",
width: 50.w,
height: 50.h,
fit: BoxFit.cover,
).circle(100.r),
],
),
SizedBox(width: 16.h),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
doctorResponseModel.doctorName!.toText16(isBold: true, maxlines: 1),
SizedBox(height: 8.h),
Wrap(
direction: Axis.horizontal,
spacing: 3.h,
runSpacing: 4.h,
children: [
AppCustomChipWidget(
labelText: (doctorResponseModel.clinicName ?? "").length > 15 ? '${doctorResponseModel.clinicName!.substring(0, 12)}...' : doctorResponseModel.clinicName ?? "",
),
AppCustomChipWidget(
labelText: (doctorResponseModel.projectName ?? "").length > 15 ? '${doctorResponseModel.projectName!.substring(0, 12)}...' : doctorResponseModel.projectName ?? ""),
AppCustomChipWidget(
labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: 6.w),
icon: AppAssets.appointment_calendar_icon,
labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(doctorResponseModel.createdOn), false),
),
],
),
],
),
),
],
),
SizedBox(height: 16.h),
Divider(color: AppColors.dividerColor, height: 1.h),
SizedBox(height: 16.h),
Padding(
padding: EdgeInsets.symmetric(horizontal: 72.w),
child: CustomButton(
text: DateUtil.formatDateToDate(DateUtil.convertStringToDate(doctorResponseModel.createdOn), false),
onPressed: () {},
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.textColor,
fontSize: 14.f,
fontWeight: FontWeight.w500,
borderRadius: 10.r,
height: 40.h,
).paddingSymmetrical(16.w, 0.h),
),
SizedBox(height: 16.h),
Row(
children: [
Image.asset(getIt.get<AppState>().getAuthenticatedUser()?.gender == 1 ? AppAssets.maleImg : AppAssets.femaleImg, width: 42.w, height: 42.h),
SizedBox(width: 8.w),
Container(
padding: EdgeInsets.all(8.w),
decoration: BoxDecoration(
color: AppColors.infoColor.withAlpha(20),
borderRadius: BorderRadius.circular(8.r),
),
child: doctorResponseModel.requestTypeDescription!.toText12(color: AppColors.infoColor, fontWeight: FontWeight.w500),
),
],
),
SizedBox(height: 24.h),
ListView.builder(
padding: EdgeInsets.zero,
itemCount: doctorResponseModel.transactions!.length,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
return Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
padding: EdgeInsets.all(8.w),
decoration: BoxDecoration(
color: AppColors.infoColor.withAlpha(20),
borderRadius: BorderRadius.circular(8.r),
),
child: doctorResponseModel.transactions![index].doctorResponse!.toText12(color: AppColors.textColor, fontWeight: FontWeight.w500),
),
SizedBox(width: 8.w),
Image.network("https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", fit: BoxFit.cover, width: 42.w, height: 42.h).circle(100.r),
],
),
],
);
},
),
],
);
}
}

@ -162,10 +162,12 @@ class _RegisterNew extends State<RegisterNew> {
GestureDetector(
onTap: () {
// Navigate to terms and conditions page
Navigator.of(context).pushNamed('/terms');
Utils.openWebView(
url: 'https://hmg.com/en/Pages/Terms.aspx',
);
},
child: Text(
LocaleKeys.termsConditoins.tr(context: context),
" ${LocaleKeys.termsConditoins.tr(context: context)}",
style: context.dynamicTextStyle(
fontSize: 14.f,
fontWeight: FontWeight.w500,

@ -24,13 +24,13 @@ class HabibWalletCard extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
LocaleKeys.myBalance.tr(context: context).toText16(isBold: true),
Row(
children: [
LocaleKeys.viewAllServices.tr(context: context).toText12(color: AppColors.primaryRedColor),
SizedBox(width: 2.h),
Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h),
],
),
// Row(
// children: [
// LocaleKeys.viewAllServices.tr(context: context).toText12(color: AppColors.primaryRedColor),
// SizedBox(width: 2.h),
// Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h),
// ],
// ),
],
).paddingSymmetrical(24.h, 0.h),
SizedBox(height: 16.h),

@ -17,6 +17,7 @@ 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/active_prescriptions/models/active_prescriptions_response_model.dart';
import 'package:hmg_patient_app_new/features/ask_doctor/ask_doctor_view_model.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/doctors_list_response_model.dart';
import 'package:hmg_patient_app_new/features/hmg_services/hmg_services_view_model.dart';
@ -38,6 +39,7 @@ import 'package:hmg_patient_app_new/presentation/allergies/allergies_list_page.d
import 'package:hmg_patient_app_new/presentation/appointments/my_appointments_page.dart';
import 'package:hmg_patient_app_new/presentation/appointments/my_doctors_page.dart';
import 'package:hmg_patient_app_new/presentation/appointments/widgets/ask_doctor_request_type_select.dart';
import 'package:hmg_patient_app_new/presentation/ask_doctor/ask_doctor_page.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/book_appointment_page.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/doctor_profile_page.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/widgets/appointment_calendar.dart';
@ -1374,7 +1376,14 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
svgIcon: AppAssets.ask_doctor_medical_file_icon,
isLargeText: true,
iconSize: 36.w,
).onPress(() {}),
).onPress(() {
getIt.get<AskDoctorViewModel>().initAskDoctorViewModel();
Navigator.of(context).push(
CustomPageRoute(
page: AskDoctorPage(),
),
);
}),
// MedicalFileCard(
// label: LocaleKeys.internetPairing.tr(context: context),
// textColor: AppColors.blackColor,

@ -24,6 +24,7 @@ class CollapsingListView extends StatelessWidget {
VoidCallback? instructions;
VoidCallback? requests;
VoidCallback? sendEmail;
VoidCallback? doctorResponse;
Widget? bottomChild;
Widget? trailing;
bool isClose;
@ -44,6 +45,7 @@ class CollapsingListView extends StatelessWidget {
this.instructions,
this.requests,
this.sendEmail,
this.doctorResponse,
this.isLeading = true,
this.trailing,
this.leadingCallback,
@ -83,6 +85,7 @@ class CollapsingListView extends StatelessWidget {
instructions: instructions,
requests: requests,
sendEmail: sendEmail,
doctorResponse: doctorResponse,
bottomChild: bottomChild,
trailing: trailing,
)
@ -114,6 +117,7 @@ class CollapsingListView extends StatelessWidget {
instructions: instructions,
requests: requests,
sendEmail: sendEmail,
doctorResponse: doctorResponse,
bottomChild: bottomChild,
trailing: trailing,
),
@ -188,6 +192,7 @@ class ScrollAnimatedTitle extends StatefulWidget implements PreferredSizeWidget
VoidCallback? instructions;
VoidCallback? requests;
VoidCallback? sendEmail;
VoidCallback? doctorResponse;
Widget? bottomChild;
Widget? trailing;
@ -203,6 +208,7 @@ class ScrollAnimatedTitle extends StatefulWidget implements PreferredSizeWidget
this.instructions,
this.requests,
this.sendEmail,
this.doctorResponse,
this.bottomChild,
this.trailing,
});
@ -277,6 +283,7 @@ class _ScrollAnimatedTitleState extends State<ScrollAnimatedTitle> {
if (widget.instructions != null) actionButton(context, t, title: LocaleKeys.instructions.tr(context: context), icon: AppAssets.requests).onPress(widget.instructions!),
if (widget.requests != null) actionButton(context, t, title: LocaleKeys.requests.tr(context: context), icon: AppAssets.insurance_history_icon).onPress(widget.requests!),
if (widget.sendEmail != null) actionButton(context, t, title: LocaleKeys.sendEmail.tr(context: context), icon: AppAssets.email).onPress(widget.sendEmail!),
if (widget.doctorResponse != null) actionButton(context, t, title: LocaleKeys.doctorResponses.tr(context: context), icon: AppAssets.doctorResponseIcon).onPress(widget.doctorResponse!),
if (widget.search != null) Utils.buildSvgWithAssets(icon: AppAssets.search_icon).onPress(widget.search!),
if (widget.trailing != null) widget.trailing!,
]

Loading…
Cancel
Save