haroon_dev
haroon amjad 3 days ago
parent d703c382e5
commit d053f58b7d

@ -811,7 +811,7 @@
"awaitingApproval": "انتظر القبول",
"news": "أخبار",
"ready": "جاهز",
"enterValidNationalId": "الرجاء إدخال رقم الهوية الوطنية أو رقم الملف الصحيح",
"enterValidNationalId": "رقم الهوية أو رقم الملف غير صحيح",
"enterValidPhoneNumber": "الرجاء إدخال رقم هاتف صالح",
"cannotEnterSaudiOrUAENumber": "لا يمكنك إدخال أرقام هواتف السعودية (00966) أو الإمارات (00971) عند اختيار دولة 'أخرى'",
"medicalCentersWithCount": "{count} مراكز طبية",
@ -1274,7 +1274,7 @@
"noVitalSignsRecordedYet": "لا توجد علامات حيوية مسجلة بعد",
"appointmentsAndVisits": "المواعيد والزيارات",
"labAndRadiology": "المختبر والأشعة",
"activeMedicationsAndPrescriptions": "الأدوية النشطة والوصفات الطبية",
"activeMedicationsAndPrescriptions": "الوصفات الطبية",
"allPrescriptions": "جميع الوصفات",
"allMedications": "جميع الأدوية",
"youDontHaveAnyPrescriptionsYet": "ليس لديك أي وصفات طبية بعد.",
@ -1586,5 +1586,6 @@
"generateAiAnalysisResult": "قم بإجراء تحليل لهذا المختبر AI",
"ratings": "التقييمات",
"hmgPharmacyText": "صيدلية الحبيب، المتجر الصيدلاني الإلكتروني المتكامل الذي تقدمه لكم مجموعة خدمات الدكتور سليمان الحبيب الطبية.",
"insuranceRequestSubmittedSuccessfully": "تم إرسال طلب تحديث بيانات التأمين بنجاح. سيتم إعلامك بمجرد الانتهاء."
"insuranceRequestSubmittedSuccessfully": "تم إرسال طلب تحديث بيانات التأمين بنجاح. سيتم إعلامك بمجرد الانتهاء.",
"updatingEmailAddress": "جارٍ تحديث عنوان البريد الإلكتروني، يرجى الانتظار..."
}

@ -802,7 +802,7 @@
"notNow": "Not Now",
"pendingActivation": "Pending Activation",
"awaitingApproval": "Awaiting Approval",
"enterValidNationalId": "Please enter a valid national ID or file number",
"enterValidNationalId": "Invalid Identification or file number",
"enterValidPhoneNumber": "Please enter a valid phone number",
"cannotEnterSaudiOrUAENumber": "You cannot enter Saudi Arabia (00966) or UAE (00971) phone numbers when 'Others' country is selected",
"ready": "Ready",
@ -1266,7 +1266,7 @@
"noVitalSignsRecordedYet": "No vital signs recorded yet",
"appointmentsAndVisits": "Appointments & visits",
"labAndRadiology": "Lab & Radiology",
"activeMedicationsAndPrescriptions": "Active Medications & Prescriptions",
"activeMedicationsAndPrescriptions": "Recent Prescriptions",
"allPrescriptions": "All Prescriptions",
"allMedications": "All Medications",
"youDontHaveAnyPrescriptionsYet": "You don't have any prescriptions yet.",
@ -1580,5 +1580,6 @@
"generateAiAnalysisResult": "Generate AI analysis for this result",
"ratings": "Ratings",
"hmgPharmacyText": "Al Habib Pharmacy, the complete online Pharmaceutical store brought to you by Dr. Sulaiman Al Habib Medical Services Group.",
"insuranceRequestSubmittedSuccessfully": "Your insurance update request has been successfully submitted. You will be notified once completed."
"insuranceRequestSubmittedSuccessfully": "Your insurance update request has been successfully submitted. You will be notified once completed.",
"updatingEmailAddress": "Updating email address, Please wait..."
}

@ -343,10 +343,14 @@
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
);
inputPaths = (
);
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
@ -360,10 +364,14 @@
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
inputPaths = (
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
@ -523,7 +531,7 @@
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 8;
CURRENT_PROJECT_VERSION = 14;
DEVELOPMENT_TEAM = 3A359E86ZF;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
@ -709,7 +717,7 @@
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 8;
CURRENT_PROJECT_VERSION = 14;
DEVELOPMENT_TEAM = 3A359E86ZF;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
@ -738,7 +746,7 @@
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 8;
CURRENT_PROJECT_VERSION = 14;
DEVELOPMENT_TEAM = 3A359E86ZF;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;

@ -101,7 +101,6 @@
<array>
<string>audio</string>
<string>fetch</string>
<string>location</string>
<string>remote-notification</string>
<string>voip</string>
</array>

@ -233,7 +233,7 @@ class ApiConsts {
static String getAiOverViewLabOrder = "Services/Patients.svc/REST/HMGAI_Lab_Analyzer_API";
// ************ static values for Api ****************
static final double appVersionID = 20.3;
static final double appVersionID = 20.5;
// static final double appVersionID = 50.7;
static final int appChannelId = 3;
@ -920,6 +920,10 @@ const DASHBOARD = 'Services/Patients.svc/REST/PatientDashboard';
const SEND_PATIENT_IMMEDIATE_UPDATE_INSURANCE_REQUEST = 'Services/OUTPs.svc/REST/PatientCompanyUpdate';
const PROFILE_SETTING = 'Services/Patients.svc/REST/GetPateintInfoForUpdate';
const SAVE_SETTING = 'Services/Patients.svc/REST/UpdatePateintInfo';
class ApiKeyConstants {
static final String googleMapsApiKey = 'AIzaSyB6TERnxIr0yJ3qG4ULBZbu0sAD4tGqtng';
}

@ -50,6 +50,7 @@ import 'package:hmg_patient_app_new/features/payfort/payfort_repo.dart';
import 'package:hmg_patient_app_new/features/payfort/payfort_view_model.dart';
import 'package:hmg_patient_app_new/features/prescriptions/prescriptions_repo.dart';
import 'package:hmg_patient_app_new/features/prescriptions/prescriptions_view_model.dart';
import 'package:hmg_patient_app_new/features/profile_settings/profile_settings_repo.dart';
import 'package:hmg_patient_app_new/features/profile_settings/profile_settings_view_model.dart';
import 'package:hmg_patient_app_new/features/qr_parking/qr_parking_repo.dart';
import 'package:hmg_patient_app_new/features/radiology/radiology_repo.dart';
@ -172,6 +173,7 @@ class AppDependencies {
getIt.registerLazySingleton<NotificationsRepo>(() => NotificationsRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
getIt.registerLazySingleton<AskDoctorRepo>(() => AskDoctorRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
getIt.registerLazySingleton<ServicesPriceListRepo>(() => ServicesPriceListRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
getIt.registerLazySingleton<ProfileSettingsRepo>(() => ProfileSettingsRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
// ViewModels
// Global/shared VMs LazySingleton
@ -224,7 +226,11 @@ class AppDependencies {
authenticationRepo: getIt(), cacheService: getIt(), navigationService: getIt(), dialogService: getIt(), appState: getIt(), errorHandlerService: getIt(), localAuthService: getIt()),
);
getIt.registerLazySingleton<ProfileSettingsViewModel>(() => ProfileSettingsViewModel(cacheService: getIt<CacheService>()));
getIt.registerLazySingleton<ProfileSettingsViewModel>(() => ProfileSettingsViewModel(
cacheService: getIt<CacheService>(),
profileSettingsRepo: getIt<ProfileSettingsRepo>(),
errorHandlerService: getIt<ErrorHandlerService>(),
));
getIt.registerLazySingleton<DateRangeSelectorRangeViewModel>(() => DateRangeSelectorRangeViewModel());

@ -4,6 +4,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:hmg_patient_app_new/core/common_models/nationality_country_model.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:hmg_patient_app_new/core/enums.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/services/dialog_service.dart';
@ -32,6 +33,13 @@ class ValidationUtils {
isCorrectID = false;
}
if(nationalId!.length == 10) {
if (Utils.isSAUDIIDValid(nationalId!) == false) {
_dialogService.showExceptionBottomSheet(message: LocaleKeys.enterValidNationalId.tr(), onOkPressed: onOkPress);
isCorrectID = false;
}
}
if (nationalId != null && nationalId.isNotEmpty && selectedCountry != null) {
if (selectedCountry == CountryEnum.saudiArabia) {
if (!validateIqama(nationalId)) {

@ -320,9 +320,9 @@ extension EmailValidator on String {
height: 32 / 32, color: color ?? AppColors.blackColor, fontSize: 32.f, letterSpacing: -1, fontFamily: isEnglishOnly ? "Poppins" : getIt.get<AppState>().getLanguageCode() == "ar" ? 'GESSTwo' : 'Poppins', fontWeight: isBold ? FontWeight.bold : weight ?? FontWeight.normal),
);
Widget toText44({Color? color, bool isBold = false}) => Text(
Widget toText44({Color? color, bool isBold = false, bool isEnglishOnly = false,}) => Text(
this,
style: TextStyle(height: 32 / 32, color: color ?? AppColors.blackColor, fontSize: 44.f, letterSpacing: -1, fontWeight: isBold ? FontWeight.bold : FontWeight.normal),
style: TextStyle(height: 32 / 32, color: color ?? AppColors.blackColor, fontSize: 44.f, letterSpacing: -1, fontWeight: isBold ? FontWeight.bold : FontWeight.normal, fontFamily: (isEnglishOnly ? "Poppins" : getIt.get<AppState>().getLanguageCode() == "ar" ? 'GESSTwo' : 'Poppins'),),
);
Widget toSectionHeading({String upperHeading = "", String lowerHeading = ""}) {

@ -28,6 +28,7 @@ import 'package:hmg_patient_app_new/features/authentication/models/resp_models/a
import 'package:hmg_patient_app_new/features/authentication/models/resp_models/check_activation_code_resp_model.dart';
import 'package:hmg_patient_app_new/features/authentication/models/resp_models/check_user_staus_nhic_response_model.dart';
import 'package:hmg_patient_app_new/features/authentication/models/resp_models/select_device_by_imei.dart';
import 'package:hmg_patient_app_new/features/hmg_services/hmg_services_view_model.dart';
import 'package:hmg_patient_app_new/features/medical_file/medical_file_view_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';
@ -619,11 +620,12 @@ class AuthenticationViewModel extends ChangeNotifier {
} else {
activation.list!.first.isParentUser = true;
}
activation.list!.first.bloodGroup = activation.patientBlodType;
activation.list!.first.bloodGroup = activation.patientBloodType;
activation.list!.first.zipCode = selectedCountrySignup == CountryEnum.others ? '0' : selectedCountrySignup.countryCode;
_appState.setAuthenticatedUser(activation.list!.first);
_appState.setPrivilegeModelList(activation.list!.first.listPrivilege!);
_appState.setUserBloodGroup = activation.patientBlodType ?? "N/A";
// _appState.setUserBloodGroup = activation.patientBlodType ?? "N/A";
_appState.setUserBloodGroup = activation.patientBloodType ?? "N/A";
}
// _appState.setUserBloodGroup = (activation.patientBlodType ?? "");
_appState.setAppAuthToken = activation.authenticationTokenId;
@ -646,6 +648,7 @@ class AuthenticationViewModel extends ChangeNotifier {
await clearDefaultInputValues();
myAppointmentsVM.setIsAppointmentDataToBeLoaded(true);
getIt.get<InsuranceViewModel>().setIsInsuranceDataToBeLoaded(true);
getIt.get<HmgServicesViewModel>().setHasVitalSignDataLoaded(false);
if (isUserAgreedBefore) {
LoaderBottomSheet.hideLoader();
navigateToHomeScreen();

@ -20,6 +20,8 @@ import 'package:hmg_patient_app_new/widgets/appbar/app_bar_widget.dart';
import 'package:provider/provider.dart';
import 'package:sms_otp_auto_verify/sms_otp_auto_verify.dart';
import 'dart:ui' as ui;
typedef OnDone = void Function(String text);
class ProvidedPinBoxTextAnimation {
@ -564,23 +566,27 @@ class _OTPVerificationScreenState extends State<OTPVerificationScreen> {
SizedBox(height: 16.h),
Center(
child: OTPWidget(
maxLength: _otpLength,
controller: _otpController,
pinBoxWidth: 70.h,
pinBoxHeight: 100.h,
pinBoxRadius: 16,
pinBoxBorderWidth: 0,
pinBoxOuterPadding: EdgeInsets.symmetric(horizontal: 4.h),
defaultBorderColor: Colors.transparent,
textBorderColor: Colors.transparent,
pinBoxColor: AppColors.whiteColor,
autoFocus: true,
onTextChanged: _onOtpChanged,
pinTextStyle: TextStyle(
fontSize: 40.f,
fontWeight: FontWeight.bold,
color: AppColors.whiteColor,
child: Directionality(
textDirection: ui.TextDirection.ltr,
child: OTPWidget(
maxLength: _otpLength,
controller: _otpController,
pinBoxWidth: 70.h,
pinBoxHeight: 100.h,
pinBoxRadius: 16,
pinBoxBorderWidth: 0,
pinBoxOuterPadding: EdgeInsets.symmetric(horizontal: 4.h),
defaultBorderColor: Colors.transparent,
textBorderColor: Colors.transparent,
pinBoxColor: AppColors.whiteColor,
autoFocus: true,
onTextChanged: _onOtpChanged,
pinTextStyle: TextStyle(
fontSize: 40.f,
fontWeight: FontWeight.bold,
color: AppColors.whiteColor,
fontFamily: "Poppins"
),
),
),
),
@ -601,7 +607,7 @@ class _OTPVerificationScreenState extends State<OTPVerificationScreen> {
children: [
LocaleKeys.resendIn.tr(context: context).toText16(color: AppColors.inputLabelTextColor),
SizedBox(width: 2.h),
' ($minutes:$seconds). '.toText16(color: AppColors.inputLabelTextColor)
' ($minutes:$seconds). '.toText16(color: AppColors.inputLabelTextColor, isEnglishOnly: true)
],
);
},

@ -85,6 +85,11 @@ class HmgServicesViewModel extends ChangeNotifier {
List<Covid19GetTestProceduresResp> covidTestProcedureList = [];
Covid19GetPaymentInfo? covidPaymentInfo;
void setHasVitalSignDataLoaded(bool hasVitalSignDataLoaded) {
this.hasVitalSignDataLoaded = hasVitalSignDataLoaded;
notifyListeners();
}
Future<void> getOrdersList() async {}
// HHC multiple services selection

@ -88,7 +88,7 @@ class InsuranceViewModel extends ChangeNotifier {
(failure) async {
debugPrint("InsuranceViewModel: API call failed - ${failure.toString()}");
isInsuranceLoading = false;
isInsuranceDataToBeLoaded = false;
isInsuranceDataToBeLoaded = true;
isInsuranceExpired = false;
isInsuranceActive = false;
notifyListeners();

@ -634,6 +634,7 @@ class MyAppointmentsViewModel extends ChangeNotifier {
Future<void> getPatientMyDoctors({Function(dynamic)? onSuccess, Function(String)? onError}) async {
// if (!isAppointmentDataToBeLoaded) return;
isPatientMyDoctorsLoading = true;
patientMyDoctorsList.clear();
notifyListeners();
final result = await myAppointmentsRepo.getPatientDoctorsList();

@ -0,0 +1,100 @@
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/services/logger_service.dart';
abstract class ProfileSettingsRepo {
/// Updates general patient info (name, phone, etc.).
Future<Either<Failure, GenericApiModel<dynamic>>> updatePatientInfo({
required Map<String, dynamic> patientInfo,
});
/// Deactivates (deletes) the patient's account.
Future<Either<Failure, GenericApiModel<dynamic>>> deactivateAccount();
}
class ProfileSettingsRepoImp implements ProfileSettingsRepo {
final ApiClient apiClient;
final LoggerService loggerService;
ProfileSettingsRepoImp({
required this.loggerService,
required this.apiClient,
});
@override
Future<Either<Failure, GenericApiModel<dynamic>>> updatePatientInfo({
required Map<String, dynamic> patientInfo,
}) async {
try {
GenericApiModel<dynamic>? apiResponse;
Failure? failure;
await apiClient.post(
SAVE_SETTING,
body: patientInfo,
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
},
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
apiResponse = GenericApiModel<dynamic>(
messageStatus: messageStatus,
statusCode: statusCode,
errorMessage: errorMessage,
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()));
}
}
@override
Future<Either<Failure, GenericApiModel<dynamic>>> deactivateAccount() async {
final Map<String, dynamic> body = {};
try {
GenericApiModel<dynamic>? apiResponse;
Failure? failure;
await apiClient.post(
// TODO: Replace with actual deactivate-account endpoint once available
'Services/Patients.svc/REST/Patient_DeactivateAccount',
body: body,
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
},
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
apiResponse = GenericApiModel<dynamic>(
messageStatus: messageStatus,
statusCode: statusCode,
errorMessage: errorMessage,
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()));
}
}
}

@ -1,18 +1,42 @@
import 'package:flutter/foundation.dart';
import 'package:hmg_patient_app_new/features/profile_settings/profile_settings_repo.dart';
import 'package:hmg_patient_app_new/services/cache_service.dart';
import 'package:hmg_patient_app_new/services/error_handler_service.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
class ProfileSettingsViewModel extends ChangeNotifier {
static const String _darkModeKey = 'is_dark_mode';
final CacheService _cacheService;
final ProfileSettingsRepo profileSettingsRepo;
final ErrorHandlerService errorHandlerService;
// Dark-mode state
bool _isDarkMode = false;
bool get isDarkMode => _isDarkMode;
ProfileSettingsViewModel({required CacheService cacheService})
: _cacheService = cacheService;
// Update email state
bool isUpdateEmailLoading = false;
bool isUpdateEmailSuccess = false;
String? updateEmailError;
// Update patient info state
bool isUpdatePatientInfoLoading = false;
bool isUpdatePatientInfoSuccess = false;
String? updatePatientInfoError;
// Deactivate account state
bool isDeactivateAccountLoading = false;
bool isDeactivateAccountSuccess = false;
String? deactivateAccountError;
ProfileSettingsViewModel({
required CacheService cacheService,
required this.profileSettingsRepo,
required this.errorHandlerService,
}) : _cacheService = cacheService;
// Dark mode
/// Call once at app startup (before the first frame) to restore the
/// persisted dark-mode preference.
@ -30,6 +54,75 @@ class ProfileSettingsViewModel extends ChangeNotifier {
notifyListeners();
}
// Update patient info
Future<void> updatePatientInfo({
required Map<String, dynamic> patientInfo,
Function(dynamic)? onSuccess,
Function(String)? onError,
}) async {
isUpdatePatientInfoLoading = true;
isUpdatePatientInfoSuccess = false;
updatePatientInfoError = null;
notifyListeners();
final result = await profileSettingsRepo.updatePatientInfo(patientInfo: patientInfo);
result.fold(
(failure) {
isUpdatePatientInfoLoading = false;
updatePatientInfoError = failure.message;
notifyListeners();
if (onError != null) {
onError(failure.message);
} else {
errorHandlerService.handleError(failure: failure);
}
},
(response) {
isUpdatePatientInfoLoading = false;
isUpdatePatientInfoSuccess = true;
notifyListeners();
onSuccess?.call(response.data);
},
);
}
// Deactivate account
Future<void> deactivateAccount({
Function(dynamic)? onSuccess,
Function(String)? onError,
}) async {
isDeactivateAccountLoading = true;
isDeactivateAccountSuccess = false;
deactivateAccountError = null;
notifyListeners();
final result = await profileSettingsRepo.deactivateAccount();
result.fold(
(failure) {
isDeactivateAccountLoading = false;
deactivateAccountError = failure.message;
notifyListeners();
if (onError != null) {
onError(failure.message);
} else {
errorHandlerService.handleError(failure: failure);
}
},
(response) {
isDeactivateAccountLoading = false;
isDeactivateAccountSuccess = true;
notifyListeners();
onSuccess?.call(response.data);
},
);
}
// Helpers
void notify() {
notifyListeners();
}

@ -1581,5 +1581,6 @@ abstract class LocaleKeys {
static const ratings = 'ratings';
static const hmgPharmacyText = 'hmgPharmacyText';
static const insuranceRequestSubmittedSuccessfully = 'insuranceRequestSubmittedSuccessfully';
static const updatingEmailAddress = 'updatingEmailAddress';
}

@ -93,8 +93,6 @@ class _MyDoctorsPageState extends State<MyDoctorsPage> {
borderRadius: 10,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 40.h,
),
SizedBox(width: 8.h),
CustomButton(
@ -280,7 +278,7 @@ class _MyDoctorsPageState extends State<MyDoctorsPage> {
runSpacing: 4.h,
children: [
AppCustomChipWidget(
labelText: isSortByClinic ? (doctor?.clinicName ?? "") : (doctor?.projectName ?? ""),
labelText: isSortByClinic ? (doctor?.projectName ?? "") : (doctor?.clinicName ?? ""),
),
],
),

@ -20,13 +20,20 @@ class DoctorRatingDetails extends StatelessWidget {
: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
bookAppointmentsVM.doctorsProfileResponseModel.actualDoctorRate!.ceilToDouble().toString().toText44(isBold: true),
bookAppointmentsVM.doctorsProfileResponseModel.actualDoctorRate!.ceilToDouble().toString().toText44(isBold: true, isEnglishOnly: true),
SizedBox(height: 4.h),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"${bookAppointmentsVM.doctorsProfileResponseModel.noOfPatientsRate} ${LocaleKeys.reviews.tr(context: context)}"
.toText16(weight: FontWeight.w500, color: AppColors.greyInfoTextColor),
Row(
children: [
"${bookAppointmentsVM.doctorsProfileResponseModel.noOfPatientsRate} "
.toText16(weight: FontWeight.w500, color: AppColors.greyInfoTextColor, isEnglishOnly: true),
LocaleKeys.reviews.tr(context: context)
.toText16(weight: FontWeight.w500, color: AppColors.greyInfoTextColor,),
],
),
RatingBar(
initialRating: bookAppointmentsVM.doctorsProfileResponseModel.actualDoctorRate!.toDouble(),
direction: Axis.horizontal,
@ -75,7 +82,7 @@ class DoctorRatingDetails extends StatelessWidget {
),
Container(
margin: EdgeInsets.only(top: 10.0, left: 10.0, right: 10.0),
child: Text("${getRatingWidth(bookAppointmentsVM.doctorDetailsList[0].ratio).round()}%", style: TextStyle(fontSize: 14.0, color: AppColors.textColor, fontWeight: FontWeight.w600)),
child: Text("${getRatingWidth(bookAppointmentsVM.doctorDetailsList[0].ratio).round()}%", style: TextStyle(fontSize: 14.0, color: AppColors.textColor, fontWeight: FontWeight.w600, fontFamily: "Poppins")),
),
],
),
@ -95,7 +102,7 @@ class DoctorRatingDetails extends StatelessWidget {
),
Container(
margin: EdgeInsets.only(top: 10.0, left: 10.0, right: 10.0),
child: Text("${bookAppointmentsVM.doctorDetailsList[1].ratio.round()}%", style: TextStyle(fontSize: 14.0, color: AppColors.textColor, fontWeight: FontWeight.w600)),
child: Text("${bookAppointmentsVM.doctorDetailsList[1].ratio.round()}%", style: TextStyle(fontSize: 14.0, color: AppColors.textColor, fontWeight: FontWeight.w600, fontFamily: "Poppins")),
),
],
),
@ -115,7 +122,7 @@ class DoctorRatingDetails extends StatelessWidget {
),
Container(
margin: EdgeInsets.only(top: 10.0, left: 10.0, right: 10.0),
child: Text("${bookAppointmentsVM.doctorDetailsList[2].ratio.round()}%", style: TextStyle(fontSize: 14.0, color: AppColors.textColor, fontWeight: FontWeight.w600)),
child: Text("${bookAppointmentsVM.doctorDetailsList[2].ratio.round()}%", style: TextStyle(fontSize: 14.0, color: AppColors.textColor, fontWeight: FontWeight.w600, fontFamily: "Poppins")),
),
],
),
@ -135,7 +142,7 @@ class DoctorRatingDetails extends StatelessWidget {
),
Container(
margin: EdgeInsets.only(top: 10.0, left: 10.0, right: 10.0),
child: Text("${bookAppointmentsVM.doctorDetailsList[3].ratio.round()}%", style: TextStyle(fontSize: 14.0, color: AppColors.textColor, fontWeight: FontWeight.w600)),
child: Text("${bookAppointmentsVM.doctorDetailsList[3].ratio.round()}%", style: TextStyle(fontSize: 14.0, color: AppColors.textColor, fontWeight: FontWeight.w600, fontFamily: "Poppins")),
),
],
),
@ -156,7 +163,7 @@ class DoctorRatingDetails extends StatelessWidget {
),
Container(
margin: EdgeInsets.only(top: 10.0, left: 10.0, right: 10.0),
child: Text("${bookAppointmentsVM.doctorDetailsList[4].ratio.round()}%", style: TextStyle(fontSize: 14.0, color: AppColors.textColor, fontWeight: FontWeight.w600)),
child: Text("${bookAppointmentsVM.doctorDetailsList[4].ratio.round()}%", style: TextStyle(fontSize: 14.0, color: AppColors.textColor, fontWeight: FontWeight.w600, fontFamily: "Poppins")),
),
],
),

@ -407,10 +407,10 @@ class _LandingPageState extends State<LandingPage> {
? myAppointmentsVM.patientAppointmentsHistoryList.length
: 3,
layout: SwiperLayout.STACK,
loop: true,
loop: false,
itemWidth: MediaQuery.of(context).size.width - 48.h,
indicatorLayout: PageIndicatorLayout.COLOR,
axisDirection: AxisDirection.right,
axisDirection: getIt.get<AppState>().isArabic() ? AxisDirection.left : AxisDirection.right,
controller: _controller,
itemHeight: 255.h + 20,
// extra space for shadow

@ -1,6 +1,7 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
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/size_utils.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
@ -92,12 +93,12 @@ class LargeServiceCard extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
serviceCardData.title.tr(context: context).toText14(isBold: true, color: AppColors.textColor),
serviceCardData.subtitle.tr(context: context).toText12(fontWeight: FontWeight.w500, color: AppColors.textColorLight),
serviceCardData.subtitle.tr(context: context).toText12(fontWeight: FontWeight.w500, color: AppColors.textColorLight, maxLine: 2),
],
),
),
],
).paddingSymmetrical(16.w, 0.h).expanded,
).paddingSymmetrical(8.w, 0.h).expanded,
CustomButton(
text: serviceCardData.isBold ? LocaleKeys.visitPharmacyOnline.tr(context: context) : LocaleKeys.bookNow.tr(context: context),
onPressed: () {
@ -177,7 +178,9 @@ class FadedLargeServiceCard extends StatelessWidget {
children: [
ClipRRect(
borderRadius: BorderRadius.circular(24.r),
child: Image.asset(serviceCardData.largeCardIcon, fit: BoxFit.cover, width: 520.w, height: 250.h),
child: Transform.flip(
flipX: getIt.get<AppState>().isArabic(),
child: Image.asset(serviceCardData.largeCardIcon, fit: BoxFit.cover, width: 520.w, height: 250.h)),
),
Positioned(
top: 0,
@ -216,11 +219,14 @@ class FadedLargeServiceCard extends StatelessWidget {
),
child: Padding(
padding: EdgeInsets.all(8.h),
child: Utils.buildSvgWithAssets(
icon: serviceCardData.icon,
iconColor: serviceCardData.iconColor,
fit: BoxFit.contain,
applyThemeColor: false
child: Transform.flip(
flipX: getIt.get<AppState>().isArabic(),
child: Utils.buildSvgWithAssets(
icon: serviceCardData.icon,
iconColor: serviceCardData.iconColor,
fit: BoxFit.contain,
applyThemeColor: false
),
),
),
),

@ -110,6 +110,7 @@ class PatientInsuranceCardUpdateCard extends StatelessWidget {
LoaderBottomSheet.hideLoader();
insuranceViewModel.setIsInsuranceDataToBeLoaded(true);
insuranceViewModel.initInsuranceProvider();
Navigator.pop(context);
}, onError: (err) {
insuranceViewModel.updatePatientInsuranceCard(
patientID: appState.getAuthenticatedUser()!.patientId!,
@ -129,9 +130,9 @@ class PatientInsuranceCardUpdateCard extends StatelessWidget {
isFullScreen: false,
isCloseButtonVisible: false,
);
Future.delayed(Duration(milliseconds: 2000)).then((value) async {
Navigator.pop(context);
});
// Future.delayed(Duration(milliseconds: 2000)).then((value) async {
// Navigator.pop(context);
// });
},
onError: (err) {
LoaderBottomSheet.hideLoader();

@ -59,7 +59,7 @@ class LabOrderByTest extends StatelessWidget {
icon: AppAssets.view_report_icon,
iconColor: AppColors.primaryRedColor,
iconSize: 16.h,
text: LocaleKeys.viewReport.tr(context: context),
text: LocaleKeys.viewResults.tr(context: context),
onPressed: () {
onTap();
},

@ -283,9 +283,9 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
),
AppCustomChipWidget(
icon: AppAssets.blood_icon,
labelText: LocaleKeys.bloodGroup.tr(namedArgs: {'bloodType': appState.getUserBloodGroup.isEmpty ? "N/A" : appState.getUserBloodGroup}, context: context),
labelText: appState.getUserBloodGroup.isEmpty ? "N/A" : appState.getUserBloodGroup,
iconColor: AppColors.primaryRedColor,
labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: 6.w),
labelPadding: EdgeInsetsDirectional.only(start: -6.w, end: 6.w),
padding: EdgeInsets.zero,
),
Consumer<InsuranceViewModel>(builder: (context, insuranceVM, child) {
@ -749,7 +749,26 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
],
).paddingSymmetrical(0.w, 0.h),
SizedBox(height: 24.h),
LocaleKeys.activeMedicationsAndPrescriptions.tr(context: context).toText16(weight: FontWeight.w500, letterSpacing: -0.2),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
LocaleKeys.activeMedicationsAndPrescriptions.tr(context: context).toText16(weight: FontWeight.w500, letterSpacing: -0.2),
Row(
children: [
LocaleKeys.viewAll.tr(context: context).toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500),
SizedBox(width: 2.w),
Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h),
],
).onPress(() {
// myAppointmentsViewModel.getPatientMyDoctors();
Navigator.of(context).push(
CustomPageRoute(
page: PrescriptionsListPage(),
),
);
}),
],
),
SizedBox(height: 16.h),
Consumer<PrescriptionsViewModel>(builder: (context, prescriptionVM, child) {
return prescriptionVM.isPrescriptionsOrdersLoading
@ -830,55 +849,55 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h),
),
SizedBox(height: 16.h),
Divider(color: AppColors.dividerColor),
SizedBox(height: 16.h),
Row(
children: [
Expanded(
child: CustomButton(
text: LocaleKeys.allPrescriptions.tr(context: context),
onPressed: () {
Navigator.of(context).push(
CustomPageRoute(
page: PrescriptionsListPage(),
),
);
},
backgroundColor: AppColors.secondaryLightRedColor,
borderColor: AppColors.secondaryLightRedColor,
textColor: AppColors.primaryRedColor,
fontSize: 12.f,
fontWeight: FontWeight.w500,
borderRadius: 12.r,
height: 40.h,
icon: AppAssets.requests,
iconColor: AppColors.primaryRedColor,
iconSize: 16.w,
),
),
SizedBox(width: 6.w),
Expanded(
child: CustomButton(
text: LocaleKeys.allMedications.tr(context: context),
onPressed: () { Navigator.of(context).push(
CustomPageRoute(
page: ActiveMedicationPage(),
),
);},
backgroundColor: AppColors.secondaryLightRedColor,
borderColor: AppColors.secondaryLightRedColor,
textColor: AppColors.primaryRedColor,
fontSize: 12.f,
fontWeight: FontWeight.w500,
borderRadius: 12.h,
height: 40.h,
icon: AppAssets.all_medications_icon,
iconColor: AppColors.primaryRedColor,
iconSize: 16.h,
),
),
],
),
// Divider(color: AppColors.dividerColor),
// SizedBox(height: 16.h),
// Row(
// children: [
// Expanded(
// child: CustomButton(
// text: LocaleKeys.allPrescriptions.tr(context: context),
// onPressed: () {
// Navigator.of(context).push(
// CustomPageRoute(
// page: PrescriptionsListPage(),
// ),
// );
// },
// backgroundColor: AppColors.secondaryLightRedColor,
// borderColor: AppColors.secondaryLightRedColor,
// textColor: AppColors.primaryRedColor,
// fontSize: 12.f,
// fontWeight: FontWeight.w500,
// borderRadius: 12.r,
// height: 40.h,
// icon: AppAssets.requests,
// iconColor: AppColors.primaryRedColor,
// iconSize: 16.w,
// ),
// ),
// SizedBox(width: 6.w),
// Expanded(
// child: CustomButton(
// text: LocaleKeys.allMedications.tr(context: context),
// onPressed: () { Navigator.of(context).push(
// CustomPageRoute(
// page: ActiveMedicationPage(),
// ),
// );},
// backgroundColor: AppColors.secondaryLightRedColor,
// borderColor: AppColors.secondaryLightRedColor,
// textColor: AppColors.primaryRedColor,
// fontSize: 12.f,
// fontWeight: FontWeight.w500,
// borderRadius: 12.h,
// height: 40.h,
// icon: AppAssets.all_medications_icon,
// iconColor: AppColors.primaryRedColor,
// iconSize: 16.h,
// ),
// ),
// ],
// ),
],
),
),
@ -911,7 +930,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h),
],
).onPress(() {
myAppointmentsViewModel.getPatientMyDoctors();
// myAppointmentsViewModel.getPatientMyDoctors();
Navigator.of(context).push(
CustomPageRoute(
page: MyDoctorsPage(),
@ -1210,6 +1229,26 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
// Requests Tab Data
return Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"${LocaleKeys.sick.tr(context: context)} ${LocaleKeys.sickSubtitle.tr(context: context)}".toText16(isBold: true),
Row(
children: [
LocaleKeys.viewAll.tr(context: context).toText12(color: AppColors.primaryRedColor),
SizedBox(width: 2.h),
Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h),
],
),
],
).onPress(() {
Navigator.of(context).push(
CustomPageRoute(
page: PatientSickleavesListPage(),
),
);
}),
SizedBox(height: 16.h),
Consumer<MedicalFileViewModel>(builder: (context, medicalFileVM, child) {
return medicalFileVM.isPatientSickLeaveListLoading
? PatientSickLeaveCard(
@ -1279,20 +1318,20 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
),
);
}),
MedicalFileCard(
label: LocaleKeys.sickLeaveReport.tr(context: context),
textColor: AppColors.blackColor,
backgroundColor: AppColors.whiteColor,
svgIcon: AppAssets.sick_leave_report_icon,
isLargeText: true,
iconSize: 36.h,
).onPress(() {
Navigator.of(context).push(
CustomPageRoute(
page: PatientSickleavesListPage(),
),
);
}),
// MedicalFileCard(
// label: LocaleKeys.sickLeaveReport.tr(context: context),
// textColor: AppColors.blackColor,
// backgroundColor: AppColors.whiteColor,
// svgIcon: AppAssets.sick_leave_report_icon,
// isLargeText: true,
// iconSize: 36.h,
// ).onPress(() {
// Navigator.of(context).push(
// CustomPageRoute(
// page: PatientSickleavesListPage(),
// ),
// );
// }),
],
).paddingSymmetrical(0.w, 0.0),
SizedBox(height: 24.h),

@ -40,18 +40,17 @@ class PatientSickLeaveCard extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"${LocaleKeys.sick.tr(context: context)} ${LocaleKeys.sickSubtitle.tr(context: context)}".toText16(isBold: true).toShimmer2(isShow: isLoading),
AppCustomChipWidget(
labelText: isLoading ? "" : getStatusText(context),
backgroundColor: getStatusColor().withOpacity(0.15),
textColor: getStatusColor(),
).toShimmer2(isShow: isLoading, width: 100.h),
],
),
SizedBox(height: 16.h),
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// AppCustomChipWidget(
// labelText: isLoading ? "" : getStatusText(context),
// backgroundColor: getStatusColor().withOpacity(0.15),
// textColor: getStatusColor(),
// ).toShimmer2(isShow: isLoading, width: 100.h),
// ],
// ),
// SizedBox(height: 16.h),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [

@ -102,7 +102,7 @@ class _FamilyCardsState extends State<FamilyCards> {
: profile.status == FamilyFileEnum.active.toInt
? AppColors.lightGreenColor
: AppColors.lightGrayBGColor,
chipText: profile.statusDescription ?? "N/A",
chipText: profile.statusDescription ?? " N/A",
iconAsset: null,
isShowBorder: false,
borderRadius: 8.h,
@ -154,7 +154,7 @@ class _FamilyCardsState extends State<FamilyCards> {
crossAxisCount: 2,
crossAxisSpacing: 10.w,
mainAxisSpacing: 10.h,
childAspectRatio: widget.isShowDetails ? 0.56.h : 0.64.h,
childAspectRatio: widget.isShowDetails ? 0.56.h : 0.74.h,
),
padding: EdgeInsets.only(bottom: 20.h),
itemBuilder: (context, index) {
@ -164,7 +164,7 @@ class _FamilyCardsState extends State<FamilyCards> {
final canSwitch = isParentUser || (!isParentUser && profile.responseId == appState.getSuperUserID);
return Container(
padding: EdgeInsets.symmetric(vertical: 15.h, horizontal: 15.h),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r),
child: Opacity(
opacity: isActive || profile.status == FamilyFileEnum.pending.toInt || !canSwitch ? 0.4 : 1.0, // Fade all content if active
child: Stack(
@ -187,7 +187,7 @@ class _FamilyCardsState extends State<FamilyCards> {
CustomChipWidget(
chipType: ChipTypeEnum.alert,
backgroundColor: AppColors.lightGrayBGColor,
chipText: "Relation:${profile.relationship ?? " N/A"}",
chipText: "Relation: ${profile.relationship ?? " N/A"}",
iconAsset: AppAssets.heart,
isShowBorder: false,
borderRadius: 8.h,

@ -24,6 +24,7 @@ import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/habib_wallet/habib_wallet_page.dart';
import 'package:hmg_patient_app_new/presentation/habib_wallet/recharge_wallet_page.dart';
import 'package:hmg_patient_app_new/presentation/insurance/widgets/insurance_update_details_card.dart';
import 'package:hmg_patient_app_new/presentation/profile_settings/widgets/update_email_widget.dart';
import 'package:hmg_patient_app_new/services/dialog_service.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/app_language_change.dart';
@ -115,7 +116,7 @@ class ProfileSettingsState extends State<ProfileSettings> {
// extra space for shadow
itemWidth: SizeUtils.width - 30.w,
indicatorLayout: PageIndicatorLayout.COLOR,
axisDirection: AxisDirection.right,
axisDirection: getIt.get<AppState>().isArabic() ? AxisDirection.left : AxisDirection.right,
controller: _controller,
pagination: SwiperPagination(
alignment: Alignment.bottomCenter,
@ -234,24 +235,24 @@ class ProfileSettingsState extends State<ProfileSettings> {
],
),
),
Container(
margin: EdgeInsets.only(left: 24.w, right: 24.w, top: 16.h, bottom: 24.h),
padding: EdgeInsets.only(top: 4.h, bottom: 4.h),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true),
child: Column(
children: [
actionItem(AppAssets.language_change, LocaleKeys.language.tr(context: context), () {
showCommonBottomSheetWithoutHeight(context, title: LocaleKeys.language.tr(context: context), child: AppLanguageChange(), callBackFunc: () {}, isFullScreen: false);
}, trailingLabel: Utils.appState.isArabic() ? "العربية" : "English"),
1.divider,
actionItem(AppAssets.bell, LocaleKeys.notificationsSettings.tr(context: context), () {
openAppSettings();
}),
// 1.divider,
// actionItem(AppAssets.touch_face_id, LocaleKeys.touchIDFaceIDServices.tr(context: context), () {}, switchValue: true),
],
),
),
// Container(
// margin: EdgeInsets.only(left: 24.w, right: 24.w, top: 16.h, bottom: 24.h),
// padding: EdgeInsets.only(top: 4.h, bottom: 4.h),
// decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true),
// child: Column(
// children: [
// actionItem(AppAssets.language_change, LocaleKeys.language.tr(context: context), () {
// showCommonBottomSheetWithoutHeight(context, title: LocaleKeys.language.tr(context: context), child: AppLanguageChange(), callBackFunc: () {}, isFullScreen: false);
// }, trailingLabel: Utils.appState.isArabic() ? "العربية" : "English"),
// 1.divider,
// actionItem(AppAssets.bell, LocaleKeys.notificationsSettings.tr(context: context), () {
// openAppSettings();
// }),
// // 1.divider,
// // actionItem(AppAssets.touch_face_id, LocaleKeys.touchIDFaceIDServices.tr(context: context), () {}, switchValue: true),
// ],
// ),
// ),
LocaleKeys.personalInformation.tr(context: context).toText18(weight: FontWeight.w600, textOverflow: TextOverflow.ellipsis, maxlines: 1).paddingOnly(left: 24.w, right: 24.w),
Container(
margin: EdgeInsets.only(left: 24.w, right: 24.w, top: 16.h, bottom: 24.h),
@ -259,7 +260,15 @@ class ProfileSettingsState extends State<ProfileSettings> {
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true),
child: Column(
children: [
actionItem(AppAssets.email_transparent, LocaleKeys.updateEmailAddress.tr(context: context), () {}),
actionItem(AppAssets.email_transparent, LocaleKeys.updateEmailAddress.tr(context: context), () {
showCommonBottomSheetWithoutHeight(
context,
title: LocaleKeys.updateEmailAddress.tr(context: context),
child: UpdateEmailDialog(),
callBackFunc: () {},
isFullScreen: false,
);
}),
// 1.divider,
// actionItem(AppAssets.smart_phone_fill, "Phone Number".needTranslation, () {}),
// 1.divider,
@ -385,10 +394,24 @@ class FamilyCardWidget extends StatelessWidget {
mainAxisSize: MainAxisSize.min,
children: [
"${profile.patientName}".toText18(isBold: true, weight: FontWeight.w600, textOverflow: TextOverflow.ellipsis, maxlines: 1, isEnglishOnly: true),
AppCustomChipWidget(
icon: AppAssets.file_icon,
labelText: "${LocaleKeys.fileNo.tr(context: context)}: ${profile.responseId}",
iconSize: 12.w,
Wrap(
direction: Axis.horizontal,
spacing: 4.w,
runSpacing: 6.w,
children: [
AppCustomChipWidget(
labelPadding: EdgeInsetsDirectional.only(start: -6.w, end: 6.w),
icon: AppAssets.file_icon,
labelText: "${LocaleKeys.fileno.tr(context: context)}: ${profile.responseId}",
iconSize: 12.w,
),
isActive ? AppCustomChipWidget(
icon: AppAssets.checkmark_icon,
labelText: LocaleKeys.verified.tr(context: context),
iconColor: AppColors.successColor,
labelPadding: EdgeInsetsDirectional.only(start: -6.w, end: 6.w),
) : SizedBox.shrink(),
],
),
],
).expanded,
@ -406,13 +429,14 @@ class FamilyCardWidget extends StatelessWidget {
AppCustomChipWidget(
labelText: LocaleKeys.ageYearsOld.tr(namedArgs: {'age': profile.age.toString(), 'yearsOld': LocaleKeys.yearsOld.tr(context: context)}),
),
isActive && appState.getAuthenticatedUser()!.bloodGroup != null
? AppCustomChipWidget(
icon: AppAssets.blood_icon,
// isActive && appState.getAuthenticatedUser()!.bloodGroup != null
// ?
isActive ? AppCustomChipWidget(
icon: AppAssets.blood_icon,
labelPadding: EdgeInsetsDirectional.only(start: -6.w, end: 8.w),
labelText: "Blood: ${appState.getAuthenticatedUser()!.bloodGroup ?? ""}",
iconColor: AppColors.primaryRedColor)
: SizedBox(),
labelText: appState.getAuthenticatedUser()!.bloodGroup ?? "N/A",
iconColor: AppColors.primaryRedColor)
: SizedBox(),
Consumer<InsuranceViewModel>(builder: (context, insuranceVM, child) {
return isActive
? AppCustomChipWidget(

@ -0,0 +1,106 @@
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/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/features/profile_settings/profile_settings_view_model.dart';
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/common_bottom_sheet.dart';
import 'package:hmg_patient_app_new/widgets/input_widget.dart';
import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
import 'package:provider/provider.dart';
class UpdateEmailDialog extends StatefulWidget {
UpdateEmailDialog({super.key});
@override
State<UpdateEmailDialog> createState() => _UpdateEmailDialogState();
}
class _UpdateEmailDialogState extends State<UpdateEmailDialog> {
late FocusNode _textFieldFocusNode;
late TextEditingController? textController;
ProfileSettingsViewModel? profileSettingsViewModel;
@override
void initState() {
_textFieldFocusNode = FocusNode();
textController = TextEditingController();
textController!.text = getIt.get<AppState>().getAuthenticatedUser()!.emailAddress ?? "";
super.initState();
}
@override
void dispose() {
_textFieldFocusNode.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
profileSettingsViewModel = Provider.of<ProfileSettingsViewModel>(context);
return GestureDetector(
onTap: () {
_textFieldFocusNode.unfocus();
FocusScope.of(context).unfocus();
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Enter the new email address to be updated in your HMG File: ".toText16(textAlign: TextAlign.start, weight: FontWeight.w500),
SizedBox(height: 12.h),
TextInputWidget(
labelText: LocaleKeys.email.tr(),
hintText: "demo@gmail.com",
controller: textController,
focusNode: _textFieldFocusNode,
autoFocus: true,
padding: EdgeInsets.all(8.h),
keyboardType: TextInputType.emailAddress,
isEnable: true,
isReadOnly: false,
prefix: null,
isBorderAllowed: false,
isAllowLeadingIcon: true,
fontSize: 14.f,
isCountryDropDown: false,
leadingIcon: AppAssets.email,
fontFamily: "Poppins",
),
SizedBox(height: 12.h),
CustomButton(
text: LocaleKeys.submit.tr(context: context),
onPressed: () {
LoaderBottomSheet.showLoader(loadingText: LocaleKeys.updatingEmailAddress.tr(context: context));
profileSettingsViewModel!.updatePatientInfo(
patientInfo: {"EmailAddress": textController!.text},
onSuccess: (response) {
LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight(context, title: LocaleKeys.success.tr(context: context), child: Utils.getSuccessWidget(loadingText: LocaleKeys.success.tr()),
callBackFunc: () async {
Navigator.of(context).pop();
}, isFullScreen: false);
},
onError: (error) {
LoaderBottomSheet.hideLoader();
// Show error message
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(error)),
);
},
);
},
backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedColor,
textColor: const Color(0xFFffffff),
),
],
),
);
}
}

@ -100,7 +100,7 @@ class _UserInfoSelectionPageState extends State<UserInfoSelectionPage> {
children: [
title.toText14(weight: FontWeight.w500),
subTitle
.toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500)
.toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500, isEnglishOnly: true)
.toShimmer2(isShow: (leadingIcon == AppAssets.rulerIcon || leadingIcon == AppAssets.weightScale) && hmgServicesVM.isVitalSignLoading),
],
),

@ -168,7 +168,7 @@ class ConditionCard extends StatelessWidget {
crossAxisAlignment: WrapCrossAlignment.center,
children: [
for (int i = 0; i < symptoms.length; i++) ...[
"${symptoms[i]}".toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor),
"${symptoms[i]}".toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor, isEnglishOnly: true),
if (i != symptoms.length - 1)
Padding(
padding: EdgeInsets.symmetric(horizontal: 2.w),
@ -228,7 +228,7 @@ class ConditionCard extends StatelessWidget {
backgroundColor: AppColors.scaffoldBgColor,
titleWidget: Row(
children: [
"$percentage%".toText12(fontWeight: FontWeight.bold, color: getChipColorBySeverityEnum(severityEnum)),
"$percentage%".toText12(fontWeight: FontWeight.bold, color: getChipColorBySeverityEnum(severityEnum), isEnglishOnly: true),
],
).paddingSymmetrical(0, 4.h),
),

@ -259,7 +259,7 @@ class _ScrollAnimatedTitleState extends State<ScrollAnimatedTitle> {
super.dispose();
}
double t = 0;
double t = 1.0;
void _onScroll() {
final double offset = widget.controller.offset;

@ -2,8 +2,8 @@ name: hmg_patient_app_new
description: "New HMG Patient App"
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
#version: 0.0.13+10
version: 0.0.1+13
version: 0.0.15+12
#version: 0.0.1+14
environment:
sdk: ">=3.6.0 <4.0.0"

Loading…
Cancel
Save