Compare commits

..

13 Commits

@ -0,0 +1,4 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.8333 3.99984C15.8333 3.26346 16.4303 2.6665 17.1667 2.6665H29.1667C29.903 2.6665 30.5 3.26346 30.5 3.99984C30.5 4.73622 29.903 5.33317 29.1667 5.33317L29.1667 23.3332C29.1667 26.6469 26.4804 29.3332 23.1667 29.3332C19.853 29.3332 17.1667 26.6469 17.1667 23.3332L17.1667 9.33405C17.1667 9.33376 17.1667 9.33434 17.1667 9.33405C17.1667 9.33376 17.1667 9.33259 17.1667 9.33229V5.33317C16.4303 5.33317 15.8333 4.73622 15.8333 3.99984ZM19.8333 7.99984V5.33317H26.5L26.5 13.0676C26.1378 13.317 25.8055 13.5125 25.4733 13.6324C25.0059 13.8012 24.5708 13.8095 24.0425 13.4925C22.6945 12.6837 21.4241 12.879 20.3715 13.4052C20.1897 13.4961 20.0098 13.5996 19.8333 13.7111V10.6665H22.5C23.2364 10.6665 23.8333 10.0695 23.8333 9.33317C23.8333 8.59679 23.2364 7.99984 22.5 7.99984H19.8333Z" fill="#2E3039"/>
<path d="M7.14104 12.6116C7.52794 12.2404 8.13873 12.2404 8.52562 12.6116L8.53329 12.6193C8.69353 12.7817 9.1478 13.2422 9.40228 13.5185C9.91854 14.0791 10.6087 14.8721 11.3012 15.7994C11.9917 16.7239 12.6985 17.8007 13.2361 18.9287C13.7693 20.0478 14.1667 21.2805 14.1667 22.4998C14.1667 24.7601 13.4124 26.4319 12.1558 27.5235C10.9246 28.5931 9.33325 28.9998 7.83333 28.9998C6.33342 28.9998 4.74203 28.5931 3.51084 27.5235C2.25425 26.4319 1.5 24.7601 1.5 22.4998C1.5 21.2805 1.89732 20.0478 2.4306 18.9287C2.96813 17.8007 3.67498 16.7239 4.36544 15.7994C5.05795 14.8721 5.74813 14.0791 6.26439 13.5185C6.51888 13.2422 6.97318 12.7817 7.1334 12.6193L7.14104 12.6116Z" fill="#2E3039"/>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

@ -176,8 +176,8 @@ class ApiClientImp implements ApiClient {
body[_appState.isAuthenticated ? 'TokenID' : 'LogInTokenID'] = _appState.appAuthToken;
}
// body['TokenID'] = "@dm!n";
// body['PatientID'] = "4767477";
body['TokenID'] = "@dm!n";
body['PatientID'] = 3628599;
}
body.removeWhere((key, value) => value == null);

@ -723,7 +723,7 @@ const DEACTIVATE_ACCOUNT = 'Services/Patients.svc/REST/PatientAppleActivation_In
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

@ -131,6 +131,7 @@ class AppAssets {
static const String smart_phone_fill = '$svgBasePath/smart_phone_fill.svg';
static const String touch_face_id = '$svgBasePath/touch_face_id.svg';
static const String minus = '$svgBasePath/minus.svg';
static const String home_lab_result_icon = '$svgBasePath/home_lab_result_icon.svg';
//bottom navigation//
static const String homeBottom = '$svgBasePath/home_bottom.svg';

@ -133,5 +133,10 @@ class AppState {
_userRegistrationPayload = value;
}
///this will be called if there is any problem in getting the user location
void resetLocation(){
userLong = 0.0;
userLong = 0.0;
}
}

@ -158,7 +158,8 @@ class AppDependencies {
bookAppointmentsRepo: getIt(),
errorHandlerService: getIt(),
navigationService: getIt(),
myAppointmentsViewModel: getIt()
myAppointmentsViewModel: getIt(),
locationUtils: getIt()
),
);

@ -1,12 +1,23 @@
import 'dart:io';
import 'dart:ui';
import 'package:geolocator/geolocator.dart';
import 'package:gms_check/gms_check.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/cache_consts.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:huawei_location/huawei_location.dart' as HmsLocation
show
FusedLocationProviderClient,
Location,
LocationSettingsRequest,
LocationRequest;
import 'package:location/location.dart'
show Location, PermissionStatus, LocationData;
import 'package:permission_handler/permission_handler.dart'
show Permission, PermissionListActions, PermissionStatusGetters;
class LocationUtils {
NavigationService navigationService;
@ -16,6 +27,7 @@ class LocationUtils {
bool isShowLocationTimeoutDialog;
bool isHuawei;
final GeolocatorPlatform _geolocatorPlatform = GeolocatorPlatform.instance;
Future<bool?>? isGMSDevice;
LocationUtils({
required this.isShowConfirmDialog,
@ -23,49 +35,62 @@ class LocationUtils {
required this.appState,
this.isHuawei = false,
this.isShowLocationTimeoutDialog = true,
});
}) {
isGMSDevice = GmsCheck().checkGmsAvailability();
}
void getCurrentLocation({Function(LatLng)? callBack}) async {
Geolocator.isLocationServiceEnabled().then((value) async {
if (value) {
await Geolocator.checkPermission().then((permission) async {
if (permission == LocationPermission.always || permission == LocationPermission.whileInUse) {
Geolocator.getLastKnownPosition().then((value) {
setLocation(value);
if (callBack != null) callBack(LatLng(value?.latitude ?? 24.7101433, value?.longitude ?? 46.6757709));
}).catchError((err) {
if (isShowConfirmDialog && isShowLocationTimeoutDialog) {}
});
void getLocation(
{Function(LatLng)? onSuccess, VoidCallback? onFailure}) async {
if (Platform.isIOS) {
getCurrentLocation(onFailure: onFailure, onSuccess: onSuccess);
return;
}
if (permission == LocationPermission.denied || permission == LocationPermission.deniedForever) {
if (Platform.isAndroid) {
// Utils.showPermissionConsentDialog(context, TranslationBase.of(context).locationPermissionDialog, () async {
final hasPermission = await _handlePermission();
if (hasPermission) {
// Geolocator.getCurrentPosition(locationSettings: LocationSettings(accuracy: LocationAccuracy.medium, timeLimit: Duration(seconds: 5))).then((value) {
Geolocator.getLastKnownPosition().then((value) {
setLocation(value);
if (callBack != null) callBack(LatLng(value?.latitude ?? 24.7101433, value?.longitude ?? 46.6757709));
});
} else {
// if (isShowConfirmDialog) showErrorLocationDialog(false, failureCallBack: () {});
if (await isGMSDevice ?? true) {
getCurrentLocation(onFailure: onFailure, onSuccess: onSuccess);
return;
}
// });
} else {
if (await Permission.location.request().isGranted) {
getCurrentLocation(callBack: callBack);
} else {
setZeroLocation();
if (isShowConfirmDialog) showErrorLocationDialog(false, failureCallBack: () {});
getHMSLocation(onFailure: onFailure, onSuccess: onSuccess);
}
void getCurrentLocation(
{Function(LatLng)? onSuccess, VoidCallback? onFailure}) async {
var location = Location();
bool isLocationEnabled = await location.serviceEnabled();
//if the location service is not enabled, ask the user to enable it
if (!isLocationEnabled) {
isLocationEnabled = await location.requestService();
if (!isLocationEnabled) {
appState.resetLocation();
onFailure?.call();
return;
}
}
}).catchError((err) {});
} else {
if (isShowConfirmDialog) showErrorLocationDialog(false, failureCallBack: () {});
LocationPermission permissionGranted = await Geolocator.checkPermission();
if (permissionGranted == LocationPermission.denied) {
permissionGranted = await Geolocator.requestPermission();
if (permissionGranted != LocationPermission.whileInUse &&
permissionGranted != LocationPermission.always) {
appState.resetLocation();
onFailure?.call();
return;
}
}
}).catchError((err) {});
Position? currentLocation = await Geolocator.getLastKnownPosition();
if(currentLocation?.latitude == null || currentLocation?.longitude == null){
currentLocation = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.low);
}
LatLng locationData = LatLng(
currentLocation?.latitude ?? 0.0, currentLocation?.longitude ?? 0.0);
saveLatLngToAppState(locationData);
onSuccess?.call(locationData);
}
Future<bool> checkIfGPSIsEnabled() async {
@ -166,4 +191,75 @@ class LocationUtils {
].request();
return (result[Permission.location]!.isGranted || result[Permission.locationAlways]!.isGranted);
}
void saveLatLngToAppState(LatLng locationData) {
appState.userLat = locationData.latitude;
appState.userLong = locationData.longitude;
}
void getHMSLocation(
{VoidCallback? onFailure, Function(LatLng p1)? onSuccess}) async {
try {
var location = Location();
HmsLocation.FusedLocationProviderClient locationService =
HmsLocation.FusedLocationProviderClient()..initFusedLocationService();
bool isLocationEnabled = await Geolocator.isLocationServiceEnabled();
//if the location service is not enabled, ask the user to enable it
if (!isLocationEnabled) {
HmsLocation.LocationRequest locationRequest =
HmsLocation.LocationRequest()
..priority = HmsLocation.LocationRequest.PRIORITY_HIGH_ACCURACY;
HmsLocation.LocationSettingsRequest request =
HmsLocation.LocationSettingsRequest(
alwaysShow: true,
needBle: false,
requests: [locationRequest],
);
await locationService.checkLocationSettings(request);
}
LocationPermission permissionGranted = await Geolocator.checkPermission();
if (permissionGranted == LocationPermission.denied) {
permissionGranted = await Geolocator.requestPermission();
if (permissionGranted != LocationPermission.whileInUse &&
permissionGranted != LocationPermission.always) {
appState.resetLocation();
onFailure?.call();
return;
}
}
HmsLocation.Location data = await locationService.getLastLocation();
if (data.latitude == null || data.longitude == null) {
appState.resetLocation();
HmsLocation.LocationRequest request = HmsLocation.LocationRequest()
..priority = HmsLocation.LocationRequest.PRIORITY_HIGH_ACCURACY
..interval = 1000 // 1 second
..numUpdates = 1;
locationService.requestLocationUpdates(request);
locationService.onLocationData?.listen((location) {
data = location;
if (data.latitude == null || data.longitude == null) {
appState.resetLocation();
onFailure?.call();
return;
}
var locationData =
LatLng(data.latitude ?? 0.0, data.longitude ?? 0.0);
saveLatLngToAppState(locationData);
onSuccess?.call(locationData);
});
} else {
var locationData = LatLng(data.latitude ?? 0.0, data.longitude ?? 0.0);
saveLatLngToAppState(locationData);
onSuccess?.call(locationData);
}
} catch (e) {
appState.resetLocation();
onFailure?.call();
}
}
}

@ -346,9 +346,9 @@ class Utils {
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Lottie.asset(AppAnimations.warningAnimation, repeat: true, reverse: false, frameRate: FrameRate(60), width: 100.h, height: 100.h, fit: BoxFit.fill),
Lottie.asset(AppAnimations.warningAnimation, repeat: true, reverse: false, frameRate: FrameRate(60), width: 128.h, height: 128.h, fit: BoxFit.fill),
SizedBox(height: 8.h),
(loadingText ?? LocaleKeys.loadingText.tr()).toText14(color: AppColors.blackColor),
(loadingText ?? LocaleKeys.loadingText.tr()).toText14(color: AppColors.blackColor, letterSpacing: 0),
SizedBox(height: 16.h),
isShowActionButtons
? Row(
@ -361,11 +361,11 @@ class Utils {
onCancelTap();
}
},
backgroundColor: AppColors.secondaryLightRedColor,
borderColor: AppColors.secondaryLightRedColor,
textColor: AppColors.primaryRedColor,
backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedColor,
textColor: AppColors.whiteColor,
icon: AppAssets.cancel,
iconColor: AppColors.primaryRedColor,
iconColor: AppColors.whiteColor,
),
),
SizedBox(width: 8.h),
@ -652,6 +652,7 @@ class Utils {
static Widget getPaymentAmountWithSymbol2(num habibWalletAmount, Color iconColor, double iconSize, {bool isSaudiCurrency = true, bool isExpanded = true}) {
return RichText(
maxLines: 1,
text: TextSpan(
children: [
WidgetSpan(

@ -30,12 +30,11 @@ extension EmailValidator on String {
fontStyle: fontStyle ?? FontStyle.normal,
fontWeight: isBold ? FontWeight.bold : FontWeight.normal,
color: color ?? AppColors.blackColor,
letterSpacing: -1,
letterSpacing: 0,
),
);
Widget toText10({Color? color, FontWeight? weight, bool isBold = false, bool isUnderLine = false, int? maxlines, FontStyle? fontStyle, TextOverflow? textOverflow, double letterSpacing = -1}) =>
Text(
Widget toText10({Color? color, FontWeight? weight, bool isBold = false, bool isUnderLine = false, int? maxlines, FontStyle? fontStyle, TextOverflow? textOverflow, double letterSpacing = 0}) => Text(
this,
maxLines: maxlines,
overflow: textOverflow,
@ -49,7 +48,7 @@ extension EmailValidator on String {
decorationColor: color ?? AppColors.blackColor),
);
Widget toText11({Color? color, FontWeight? weight, bool isUnderLine = false, bool isCenter = false, bool isBold = false, int maxLine = 0, double letterSpacing = -1}) => Text(
Widget toText11({Color? color, FontWeight? weight, bool isUnderLine = false, bool isCenter = false, bool isBold = false, int maxLine = 0, double letterSpacing = 0}) => Text(
this,
textAlign: isCenter ? TextAlign.center : null,
maxLines: (maxLine > 0) ? maxLine : null,
@ -71,7 +70,7 @@ extension EmailValidator on String {
fontSize: 12.fSize,
fontWeight: fontWeight ?? (isBold ? FontWeight.bold : FontWeight.normal),
color: color ?? AppColors.blackColor,
letterSpacing: -1,
letterSpacing: 0,
height: height,
decorationColor: isUnderLine ? AppColors.blackColor : null,
decoration: isUnderLine ? TextDecoration.underline : null,
@ -87,7 +86,7 @@ extension EmailValidator on String {
fontSize: 12.fSize,
fontWeight: isBold ? FontWeight.bold : FontWeight.normal,
color: color ?? AppColors.blackColor,
letterSpacing: -1,
letterSpacing: 0,
decoration: isUnderLine ? TextDecoration.underline : null,
),
);
@ -120,7 +119,7 @@ extension EmailValidator on String {
),
);
Widget toText13({Color? color, bool isUnderLine = false, bool isBold = false, bool isCenter = false, int maxLine = 0, FontWeight? weight, double? letterSpacing = -1}) => Text(
Widget toText13({Color? color, bool isUnderLine = false, bool isBold = false, bool isCenter = false, int maxLine = 0, FontWeight? weight, double? letterSpacing = 0}) => Text(
this,
textAlign: isCenter ? TextAlign.center : null,
maxLines: (maxLine > 0) ? maxLine : null,
@ -139,7 +138,7 @@ extension EmailValidator on String {
bool isCenter = false,
FontWeight? weight,
int? maxlines,
double? letterSpacing = -1,
double? letterSpacing = 0,
double? height,
TextOverflow? textOverflow}) =>
Text(

@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/cache_consts.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:hmg_patient_app_new/core/location_util.dart';
import 'package:hmg_patient_app_new/core/utils/date_util.dart';
import 'package:hmg_patient_app_new/core/utils/doctor_response_mapper.dart';
import 'package:hmg_patient_app_new/core/utils/loading_utils.dart';
@ -24,6 +25,7 @@ import 'package:hmg_patient_app_new/presentation/home/navigation_screen.dart';
import 'package:hmg_patient_app_new/services/error_handler_service.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart';
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
import 'package:location/location.dart' show Location;
@ -37,6 +39,8 @@ class BookAppointmentsViewModel extends ChangeNotifier {
int initialSlotDuration = 0;
LocationUtils locationUtils;
List<GetClinicsListResponseModel> clinicsList = [];
List<GetClinicsListResponseModel> _filteredClinicsList = [];
@ -74,7 +78,9 @@ class BookAppointmentsViewModel extends ChangeNotifier {
bool shouldLoadSpecificClinic = false;
String? currentlySelectedHospitalFromRegionFlow;
BookAppointmentsViewModel({required this.bookAppointmentsRepo, required this.errorHandlerService, required this.navigationService, required this.myAppointmentsViewModel});
BookAppointmentsViewModel({required this.bookAppointmentsRepo, required this.errorHandlerService, required this.navigationService, required this.myAppointmentsViewModel, required this.locationUtils}) {;
initBookAppointmentViewModel();
}
void initializeFilteredList() {
_filteredClinicsList = List.from(clinicsList);
@ -97,6 +103,7 @@ class BookAppointmentsViewModel extends ChangeNotifier {
isDoctorProfileLoading = true;
clinicsList.clear();
doctorsList.clear();
// getLocation();
notifyListeners();
}
@ -378,7 +385,7 @@ class BookAppointmentsViewModel extends ChangeNotifier {
LoadingUtils.hideFullScreenLoader();
Navigator.pushAndRemoveUntil(
navigationService.navigatorKey.currentContext!,
FadePage(
CustomPageRoute(
page: LandingNavigation(),
),
(r) => false);
@ -408,10 +415,10 @@ class BookAppointmentsViewModel extends ChangeNotifier {
Future<void> getRegionMappedProjectList() async {
//todo handle the case in the location is switch on
if(hospitalList != null && hospitalList!.registeredDoctorMap != null && hospitalList!.registeredDoctorMap!.isNotEmpty){
filteredHospitalList = hospitalList;
return;
}
// if(hospitalList != null && hospitalList!.registeredDoctorMap != null && hospitalList!.registeredDoctorMap!.isNotEmpty){
// filteredHospitalList = hospitalList;
// return;
// }
isRegionListLoading = true;
notifyListeners();
final result = await bookAppointmentsRepo.getProjectList();
@ -429,10 +436,8 @@ class BookAppointmentsViewModel extends ChangeNotifier {
lat: _appState.userLat,
lng: _appState.userLong,
);
var lat = await Utils.getNumFromPrefs(CacheConst.userLat);
var lng = await Utils.getNumFromPrefs(CacheConst.userLong);
var isLocationEnabled = (lat != 0) && (lng != 0);
var isLocationEnabled = (_appState.userLat != 0) && (_appState.userLong != 0);
hospitalList =
await DoctorMapper.sortList(isLocationEnabled, hospitalList!);
@ -480,15 +485,15 @@ class BookAppointmentsViewModel extends ChangeNotifier {
notifyListeners();
}
Future<bool> isLocationEnabled() async{
return await Location().serviceEnabled();
bool isLocationEnabled() {
return _appState.userLong != 0.0 && _appState.userLong != 0.0;
}
bool getLocationStatus() {
bool isLocationAvaiable = false;
isLocationEnabled().then((value) => isLocationAvaiable = value);
return isLocationAvaiable;
}
// bool getLocationStatus() {
// bool isLocationAvaiable = false;
// isLocationEnabled().then((value) => isLocationAvaiable = value);
// return isLocationAvaiable;
// }
void setLoadSpecificClinic(bool status) {
shouldLoadSpecificClinic = status;
@ -518,4 +523,9 @@ class BookAppointmentsViewModel extends ChangeNotifier {
void resetFilterList(){
filteredHospitalList = hospitalList;
}
void getLocation(){
locationUtils.getLocation();
}
}

@ -2,6 +2,7 @@ import 'package:flutter/foundation.dart' show ChangeNotifier;
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/doctor_list_api_response.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/select_clinic_page.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
enum AppointmentViaRegionState {
@ -39,7 +40,7 @@ class AppointmentViaRegionViewmodel extends ChangeNotifier {
void handleLastStep(){
navigationService.pop();
navigationService.push(FadePage(
navigationService.push(CustomPageRoute(
page: SelectClinicPage(),
),);
}

@ -79,6 +79,11 @@ class MyAppointmentsViewModel extends ChangeNotifier {
}
Future<void> getPatientAppointments(bool isActiveAppointment, bool isArrivedAppointments, {Function(dynamic)? onSuccess, Function(String)? onError}) async {
patientAppointmentsHistoryList.clear();
patientUpcomingAppointmentsHistoryList.clear();
patientArrivedAppointmentsHistoryList.clear();
final result = await myAppointmentsRepo.getPatientAppointments(isActiveAppointment: isActiveAppointment, isArrivedAppointments: isArrivedAppointments);
final resultArrived = await myAppointmentsRepo.getPatientAppointments(isActiveAppointment: false, isArrivedAppointments: true);

@ -99,6 +99,7 @@ class PayfortViewModel extends ChangeNotifier {
String? applePayShaType,
String? applePayShaRequestPhrase,
}) async {
var sdkTokenResponse;
try {
String? deviceId = await _payfort.getDeviceId();
@ -125,6 +126,7 @@ class PayfortViewModel extends ChangeNotifier {
// dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
} else if (apiResponse.messageStatus == 1) {
// payfortProjectDetailsRespModel = apiResponse.data!;
sdkTokenResponse = apiResponse.data;
isApplePayConfigurationLoading = false;
notifyListeners();
}
@ -133,7 +135,7 @@ class PayfortViewModel extends ChangeNotifier {
} catch (e) {
print("Error here: ${e.toString()}");
}
return null;
return sdkTokenResponse;
}
Future<void> paymentWithApplePay({

@ -1,3 +1,5 @@
import 'package:hmg_patient_app_new/core/utils/date_util.dart';
class PatientRadiologyResponseModel {
String? setupID;
int? projectID;
@ -6,7 +8,7 @@ class PatientRadiologyResponseModel {
int? invoiceNo;
int? doctorID;
int? clinicID;
String? orderDate;
DateTime? orderDate;
String? reportData;
String? imageURL;
String? procedureID;
@ -120,7 +122,7 @@ class PatientRadiologyResponseModel {
invoiceNo = json['InvoiceNo'];
doctorID = json['DoctorID'];
clinicID = json['ClinicID'];
orderDate = json['OrderDate'];
orderDate = DateUtil.convertStringToDate(json['OrderDate']);
reportData = json['ReportData'];
imageURL = json['ImageURL'];
procedureID = json['ProcedureID'];

@ -3,11 +3,17 @@ 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/utils.dart';
import 'package:hmg_patient_app_new/features/authentication/models/resp_models/authenticated_user_resp_model.dart';
import 'package:hmg_patient_app_new/features/radiology/models/resp_models/patient_radiology_response_model.dart';
import 'package:hmg_patient_app_new/services/logger_service.dart';
abstract class RadiologyRepo {
Future<Either<Failure, GenericApiModel<List<PatientRadiologyResponseModel>>>> getPatientRadiologyOrders({required String patientId});
Future<Either<Failure, GenericApiModel<String>>> getRadiologyImage({required PatientRadiologyResponseModel patientRadiologyResponseModel});
Future<Either<Failure, GenericApiModel<String>>> getRadiologyReportPDF({required PatientRadiologyResponseModel patientRadiologyResponseModel, required AuthenticatedUser authenticatedUser});
}
class RadiologyRepoImp implements RadiologyRepo {
@ -58,4 +64,99 @@ class RadiologyRepoImp implements RadiologyRepo {
return Left(UnknownFailure(e.toString()));
}
}
@override
Future<Either<Failure, GenericApiModel<String>>> getRadiologyImage({required PatientRadiologyResponseModel patientRadiologyResponseModel}) async {
Map<String, dynamic> mapDevice = {
"InvoiceNo": Utils.isVidaPlusProject(patientRadiologyResponseModel.projectID!) ? "0" : patientRadiologyResponseModel.invoiceNo,
"InvoiceNo_VP": Utils.isVidaPlusProject(patientRadiologyResponseModel.projectID!) ? patientRadiologyResponseModel.invoiceNo : "0",
"LineItemNo": patientRadiologyResponseModel.invoiceLineItemNo,
"ProjectID": patientRadiologyResponseModel.projectID!,
"InvoiceType": patientRadiologyResponseModel.invoiceType!,
"ExamId": patientRadiologyResponseModel.examId ?? "",
};
try {
GenericApiModel<String>? apiResponse;
Failure? failure;
await apiClient.post(
GET_RAD_IMAGE_URL,
body: mapDevice,
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
},
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
apiResponse = GenericApiModel<String>(
messageStatus: messageStatus,
statusCode: statusCode,
errorMessage: null,
data: response["Data"],
);
} 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<String>>> getRadiologyReportPDF({required PatientRadiologyResponseModel patientRadiologyResponseModel, required AuthenticatedUser authenticatedUser}) async {
Map<String, dynamic> mapDevice = {
"InvoiceNo": Utils.isVidaPlusProject(patientRadiologyResponseModel.projectID!) ? 0 : patientRadiologyResponseModel.invoiceNo,
"InvoiceNo_VP": Utils.isVidaPlusProject(patientRadiologyResponseModel.projectID!) ? patientRadiologyResponseModel.invoiceNo : 0,
"LineItemNo": patientRadiologyResponseModel.invoiceLineItemNo,
"InvoiceLineItemNo": patientRadiologyResponseModel.invoiceLineItemNo,
"ProjectID": patientRadiologyResponseModel.projectID!,
"InvoiceType": patientRadiologyResponseModel.invoiceType!,
"SetupID": patientRadiologyResponseModel.setupID!,
// "ExamId": patientRadiologyResponseModel.examId ?? "",
"IsDownload": true,
'ClinicName': patientRadiologyResponseModel.clinicDescription,
'DateofBirth': authenticatedUser.dateofBirth,
'DoctorName': patientRadiologyResponseModel.doctorName,
'OrderDate': '${patientRadiologyResponseModel.orderDate!.year}-${patientRadiologyResponseModel.orderDate!.month}-${patientRadiologyResponseModel.orderDate!.day}',
'PatientIditificationNum': authenticatedUser.patientIdentificationNo,
'PatientMobileNumber': authenticatedUser.mobileNumber,
'PatientName': "${authenticatedUser.firstName!} ${authenticatedUser.lastName!}",
'ProjectName': patientRadiologyResponseModel.projectName,
'RadResult': patientRadiologyResponseModel.reportData,
"To": authenticatedUser.emailAddress
};
try {
GenericApiModel<String>? apiResponse;
Failure? failure;
await apiClient.post(
SEND_RAD_REPORT_EMAIL,
body: mapDevice,
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
},
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
apiResponse = GenericApiModel<String>(
messageStatus: messageStatus,
statusCode: statusCode,
errorMessage: null,
data: response["Base64Data"],
);
} 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,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/features/authentication/models/resp_models/authenticated_user_resp_model.dart';
import 'package:hmg_patient_app_new/features/radiology/radiology_repo.dart';
import 'package:hmg_patient_app_new/services/error_handler_service.dart';
@ -6,17 +7,23 @@ import 'models/resp_models/patient_radiology_response_model.dart';
class RadiologyViewModel extends ChangeNotifier {
bool isRadiologyOrdersLoading = false;
bool isRadiologyPDFReportLoading = false;
RadiologyRepo radiologyRepo;
ErrorHandlerService errorHandlerService;
List<PatientRadiologyResponseModel> patientRadiologyOrders = [];
String radiologyImageURL = "";
String patientRadiologyReportPDFBase64 = "";
RadiologyViewModel({required this.radiologyRepo, required this.errorHandlerService});
initRadiologyProvider() {
patientRadiologyOrders.clear();
isRadiologyOrdersLoading = true;
isRadiologyPDFReportLoading = true;
radiologyImageURL = "";
getPatientRadiologyOrders();
notifyListeners();
}
@ -40,4 +47,50 @@ class RadiologyViewModel extends ChangeNotifier {
},
);
}
Future<void> getRadiologyImage({required PatientRadiologyResponseModel patientRadiologyResponseModel, Function(dynamic)? onSuccess, Function(String)? onError}) async {
final result = await radiologyRepo.getRadiologyImage(patientRadiologyResponseModel: patientRadiologyResponseModel);
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) {
radiologyImageURL = apiResponse.data!;
notifyListeners();
if (onSuccess != null) {
onSuccess(apiResponse);
}
}
},
);
}
Future<void> getRadiologyPDF(
{required PatientRadiologyResponseModel patientRadiologyResponseModel, required AuthenticatedUser authenticatedUser, Function(dynamic)? onSuccess, Function(String)? onError}) async {
final result = await radiologyRepo.getRadiologyReportPDF(patientRadiologyResponseModel: patientRadiologyResponseModel, authenticatedUser: authenticatedUser);
result.fold(
(failure) async => await errorHandlerService.handleError(
failure: failure,
onOkPressed: () {
onError!(failure.message);
},
),
(apiResponse) {
if (apiResponse.messageStatus == 2) {
onError!(apiResponse.errorMessage!);
// dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
} else if (apiResponse.messageStatus == 1) {
patientRadiologyReportPDFBase64 = apiResponse.data!;
isRadiologyPDFReportLoading = false;
notifyListeners();
if (onSuccess != null) {
onSuccess(apiResponse);
}
}
},
);
}
}

@ -132,6 +132,7 @@ void main() async {
errorHandlerService: getIt(),
navigationService: getIt(),
myAppointmentsViewModel: getIt(),
locationUtils: getIt(),
),
),
ChangeNotifierProvider<AuthenticationViewModel>(

@ -28,6 +28,7 @@ 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/loader/bottomsheet_loader.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:hmg_patient_app_new/widgets/shimmer/movies_shimmer_widget.dart';
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
import 'package:maps_launcher/maps_launcher.dart';
@ -72,7 +73,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
Expanded(
child: CollapsingListView(
title: "Appointment Details".needTranslation,
report: () {},
report: AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel) ? () {} : null,
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
@ -331,7 +332,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
).onPress(() {
prescriptionVM.setPrescriptionsDetailsLoading();
Navigator.of(context).push(
FadePage(
CustomPageRoute(
page: PrescriptionDetailPage(prescriptionsResponseModel: getPrescriptionRequestModel()),
),
);
@ -364,7 +365,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
onPressed: () {
Navigator.of(context)
.push(
FadePage(
CustomPageRoute(
page: PrescriptionsListPage(),
),
)
@ -425,8 +426,8 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
LocaleKeys.upcomingPaymentNow.tr(context: context).toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor),
"VAT 15%(${widget.patientAppointmentHistoryResponseModel.patientTaxAmount})".needTranslation.toText14(isBold: true, color: AppColors.greyTextColor),
Expanded(child: LocaleKeys.upcomingPaymentNow.tr(context: context).toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor)),
"VAT 15%(${widget.patientAppointmentHistoryResponseModel.patientTaxAmount})".needTranslation.toText14(isBold: true, color: AppColors.greyTextColor, letterSpacing: -2),
],
),
SizedBox(height: 18.h),
@ -560,7 +561,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
case 20:
myAppointmentsViewModel.setIsPatientAppointmentShareLoading(true);
Navigator.of(context).push(
FadePage(
CustomPageRoute(
page: AppointmentPaymentPage(patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel),
),
);

@ -27,6 +27,7 @@ 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/in_app_browser/InAppBrowser.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:hmg_patient_app_new/widgets/shimmer/movies_shimmer_widget.dart';
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
import 'package:provider/provider.dart';
@ -79,9 +80,7 @@ class _AppointmentPaymentPageState extends State<AppointmentPaymentPage> {
child: CollapsingListView(
title: "Appointment Payment".needTranslation,
child: SingleChildScrollView(
child: myAppointmentsVM.isAppointmentPatientShareLoading
? const MoviesShimmerWidget().paddingAll(24.h)
: Column(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 24.h),
@ -97,9 +96,9 @@ class _AppointmentPaymentPageState extends State<AppointmentPaymentPage> {
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Image.asset(AppAssets.mada, width: 72.h, height: 25.h),
Image.asset(AppAssets.mada, width: 72.h, height: 25.h).toShimmer2(isShow: myAppointmentsVM.isAppointmentPatientShareLoading),
SizedBox(height: 16.h),
"Mada".needTranslation.toText16(isBold: true),
"Mada".needTranslation.toText16(isBold: true).toShimmer2(isShow: myAppointmentsVM.isAppointmentPatientShareLoading),
],
),
SizedBox(width: 8.h),
@ -110,7 +109,7 @@ class _AppointmentPaymentPageState extends State<AppointmentPaymentPage> {
width: 18.h,
height: 13.h,
fit: BoxFit.contain,
),
).toShimmer2(isShow: myAppointmentsVM.isAppointmentPatientShareLoading),
],
).paddingSymmetrical(16.h, 16.h),
).paddingSymmetrical(24.h, 0.h).onPress(() {
@ -136,9 +135,9 @@ class _AppointmentPaymentPageState extends State<AppointmentPaymentPage> {
SizedBox(width: 8.h),
Image.asset(AppAssets.Mastercard, width: 40.h, height: 40.h),
],
),
).toShimmer2(isShow: myAppointmentsVM.isAppointmentPatientShareLoading),
SizedBox(height: 16.h),
"Visa or Mastercard".needTranslation.toText16(isBold: true),
"Visa or Mastercard".needTranslation.toText16(isBold: true).toShimmer2(isShow: myAppointmentsVM.isAppointmentPatientShareLoading),
],
),
SizedBox(width: 8.h),
@ -149,7 +148,7 @@ class _AppointmentPaymentPageState extends State<AppointmentPaymentPage> {
width: 18.h,
height: 13.h,
fit: BoxFit.contain,
),
).toShimmer2(isShow: myAppointmentsVM.isAppointmentPatientShareLoading),
],
).paddingSymmetrical(16.h, 16.h),
).paddingSymmetrical(24.h, 0.h).onPress(() {
@ -169,9 +168,9 @@ class _AppointmentPaymentPageState extends State<AppointmentPaymentPage> {
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Image.asset(AppAssets.tamara_en, width: 72.h, height: 25.h),
Image.asset(AppAssets.tamara_en, width: 72.h, height: 25.h).toShimmer2(isShow: myAppointmentsVM.isAppointmentPatientShareLoading),
SizedBox(height: 16.h),
"Tamara".needTranslation.toText16(isBold: true),
"Tamara".needTranslation.toText16(isBold: true).toShimmer2(isShow: myAppointmentsVM.isAppointmentPatientShareLoading),
],
),
SizedBox(width: 8.h),
@ -182,7 +181,7 @@ class _AppointmentPaymentPageState extends State<AppointmentPaymentPage> {
width: 18.h,
height: 13.h,
fit: BoxFit.contain,
),
).toShimmer2(isShow: myAppointmentsVM.isAppointmentPatientShareLoading),
],
).paddingSymmetrical(16.h, 16.h),
).paddingSymmetrical(24.h, 0.h).onPress(() {
@ -204,9 +203,7 @@ class _AppointmentPaymentPageState extends State<AppointmentPaymentPage> {
),
child: Consumer<PayfortViewModel>(builder: (context, payfortVM, child) {
//TODO: Need to add loading state & animation for Apple Pay Configuration
return payfortVM.isApplePayConfigurationLoading
? const MoviesShimmerWidget().paddingAll(16.h)
: Column(
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
(myAppointmentsVM.patientAppointmentShareResponseModel!.isCash ?? true)
@ -227,7 +224,7 @@ class _AppointmentPaymentPageState extends State<AppointmentPaymentPage> {
text: LocaleKeys.updateInsurance.tr(context: context),
onPressed: () {
Navigator.of(context).push(
FadePage(
CustomPageRoute(
page: InsuranceHomePage(),
),
);
@ -272,13 +269,13 @@ class _AppointmentPaymentPageState extends State<AppointmentPaymentPage> {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"".needTranslation.toText14(isBold: true),
Utils.getPaymentAmountWithSymbol(
myAppointmentsVM.patientAppointmentShareResponseModel!.patientShareWithTax!.toString().toText24(isBold: true), AppColors.blackColor, 17,
Utils.getPaymentAmountWithSymbol(myAppointmentsVM.patientAppointmentShareResponseModel!.patientShareWithTax!.toString().toText24(isBold: true), AppColors.blackColor, 17,
isSaudiCurrency: true),
],
).paddingSymmetrical(24.h, 0.h),
//TODO: Add Apple Pay Privileges
Utils.buildSvgWithAssets(
Platform.isIOS
? Utils.buildSvgWithAssets(
icon: AppAssets.apple_pay_button,
width: 200.h,
height: 80.h,
@ -286,7 +283,8 @@ class _AppointmentPaymentPageState extends State<AppointmentPaymentPage> {
).paddingSymmetrical(24.h, 0.h).onPress(() {
// payfortVM.setIsApplePayConfigurationLoading(true);
startApplePay();
}),
})
: SizedBox(height: 12.h),
SizedBox(height: 12.h),
],
);
@ -389,12 +387,12 @@ class _AppointmentPaymentPageState extends State<AppointmentPaymentPage> {
Navigator.of(context).pop();
Navigator.pushAndRemoveUntil(
context,
FadePage(
CustomPageRoute(
page: LandingNavigation(),
),
(r) => false);
Navigator.of(context).push(
FadePage(page: MyAppointmentsPage()),
CustomPageRoute(page: MyAppointmentsPage()),
);
});
});
@ -528,6 +526,7 @@ class _AppointmentPaymentPageState extends State<AppointmentPaymentPage> {
onSucceeded: (successResult) async {
Navigator.of(context).pop();
log("successResult: ${successResult.responseMessage.toString()}");
selectedPaymentMethod = successResult.paymentOption ?? "VISA";
checkPaymentStatus();
},
// projectId: appo.projectID,

@ -6,6 +6,7 @@ import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/my_appointments/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/presentation/appointments/widgets/appointment_card.dart';
import 'package:hmg_patient_app_new/presentation/lab/collapsing_list_view.dart';
@ -53,7 +54,6 @@ class _MyAppointmentsPageState extends State<MyAppointmentsPage> {
CustomTabBarModel(null, "Completed".needTranslation),
],
onTabChange: (index) {
print(index);
myAppointmentsViewModel.onTabChange(index);
},
).paddingSymmetrical(24.h, 0.h),
@ -86,7 +86,15 @@ class _MyAppointmentsPageState extends State<MyAppointmentsPage> {
: 1,
itemBuilder: (context, index) {
return myAppointmentsVM.isMyAppointmentsLoading
? const MoviesShimmerWidget().paddingSymmetrical(24.h, 0.h)
? Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true),
child: AppointmentCard(
patientAppointmentHistoryResponseModel: PatientAppointmentHistoryResponseModel(),
myAppointmentsViewModel: myAppointmentsViewModel,
isLoading: true,
isFromHomePage: false,
),
).paddingSymmetrical(24.h, 0.h)
: myAppointmentsVM.patientAppointmentsHistoryList.isNotEmpty
? AnimationConfiguration.staggeredList(
position: index,
@ -101,6 +109,8 @@ class _MyAppointmentsPageState extends State<MyAppointmentsPage> {
child: AppointmentCard(
patientAppointmentHistoryResponseModel: myAppointmentsVM.patientAppointmentsHistoryList[index],
myAppointmentsViewModel: myAppointmentsViewModel,
isLoading: false,
isFromHomePage: false,
),
).paddingSymmetrical(24.h, 0.h),
),

@ -16,14 +16,16 @@ import 'package:hmg_patient_app_new/presentation/appointments/appointment_detail
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/routes/custom_page_route.dart';
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
import 'package:smooth_corner/smooth_corner.dart';
class AppointmentCard extends StatefulWidget {
AppointmentCard({super.key, required this.patientAppointmentHistoryResponseModel, required this.myAppointmentsViewModel});
AppointmentCard({super.key, required this.patientAppointmentHistoryResponseModel, required this.myAppointmentsViewModel, this.isLoading = false, this.isFromHomePage = false});
PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel;
MyAppointmentsViewModel myAppointmentsViewModel;
bool isLoading;
bool isFromHomePage;
@override
State<AppointmentCard> createState() => _AppointmentCardState();
@ -37,7 +39,7 @@ class _AppointmentCardState extends State<AppointmentCard> {
onTap: () {
Navigator.of(context)
.push(
FadePage(
CustomPageRoute(
page: AppointmentDetailsPage(patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel),
),
)
@ -65,7 +67,9 @@ class _AppointmentCardState extends State<AppointmentCard> {
mainAxisSize: MainAxisSize.min,
children: [
CustomButton(
text: appState.isArabic()
text: widget.isLoading
? "OutPatient"
: appState.isArabic()
? widget.patientAppointmentHistoryResponseModel.isInOutPatientDescriptionN!
: widget.patientAppointmentHistoryResponseModel.isInOutPatientDescription!,
onPressed: () {},
@ -84,7 +88,7 @@ class _AppointmentCardState extends State<AppointmentCard> {
mainAxisSize: MainAxisSize.min,
children: [
CustomButton(
text: AppointmentType.getAppointmentStatusType(widget.patientAppointmentHistoryResponseModel.patientStatusType!),
text: widget.isLoading ? "Booked" : AppointmentType.getAppointmentStatusType(widget.patientAppointmentHistoryResponseModel.patientStatusType!),
onPressed: () {},
backgroundColor: AppColors.successColor.withOpacity(0.1),
borderColor: AppColors.successColor.withOpacity(0.0),
@ -98,11 +102,11 @@ class _AppointmentCardState extends State<AppointmentCard> {
],
),
],
),
).toShimmer2(isShow: widget.isLoading),
),
// TODO: Implement the logic to enable/disable the switch based on reminder status
AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel)
? SizedBox()
? SizedBox().toShimmer2(isShow: widget.isLoading)
: Switch(
activeColor: AppColors.successColor,
activeTrackColor: AppColors.successColor.withValues(alpha: .15),
@ -114,13 +118,13 @@ class _AppointmentCardState extends State<AppointmentCard> {
return const Icon(Icons.close); // Icon when switch is OFF
},
),
value: widget.patientAppointmentHistoryResponseModel.hasReminder!,
value: widget.isLoading ? false : widget.patientAppointmentHistoryResponseModel.hasReminder!,
onChanged: (newValue) {
setState(() {
widget.myAppointmentsViewModel.setAppointmentReminder(newValue, widget.patientAppointmentHistoryResponseModel);
});
},
),
).toShimmer2(isShow: widget.isLoading),
],
),
SizedBox(height: 16.h),
@ -128,30 +132,38 @@ class _AppointmentCardState extends State<AppointmentCard> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Image.network(
widget.patientAppointmentHistoryResponseModel.doctorImageURL!,
widget.isLoading ? "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png" : widget.patientAppointmentHistoryResponseModel.doctorImageURL!,
width: 63.h,
height: 63.h,
fit: BoxFit.fill,
).circle(100),
).circle(100).toShimmer2(isShow: widget.isLoading),
SizedBox(width: 16.h),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
widget.patientAppointmentHistoryResponseModel.doctorNameObj!.toText16(isBold: true),
(widget.isLoading ? "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png" : widget.patientAppointmentHistoryResponseModel.doctorNameObj!)
.toText16(isBold: true)
.toShimmer2(isShow: widget.isLoading),
SizedBox(height: 8.h),
Wrap(
direction: Axis.horizontal,
spacing: 3.h,
runSpacing: 4.h,
children: [
AppCustomChipWidget(labelText: widget.patientAppointmentHistoryResponseModel.clinicName!),
AppCustomChipWidget(labelText: widget.patientAppointmentHistoryResponseModel.projectName!),
widget.isFromHomePage ? SizedBox.shrink() : AppCustomChipWidget(labelText: widget.isLoading ? "Cardiology" : widget.patientAppointmentHistoryResponseModel.clinicName!).toShimmer2(isShow: widget.isLoading),
widget.isFromHomePage ? SizedBox.shrink() : AppCustomChipWidget(labelText: widget.isLoading ? "Olaya" : widget.patientAppointmentHistoryResponseModel.projectName!).toShimmer2(isShow: widget.isLoading),
AppCustomChipWidget(
icon: AppAssets.appointment_calendar_icon,
labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(widget.patientAppointmentHistoryResponseModel.appointmentDate), false)),
labelText:
widget.isLoading ? "Cardiology" : DateUtil.formatDateToDate(DateUtil.convertStringToDate(widget.patientAppointmentHistoryResponseModel.appointmentDate), false))
.toShimmer2(isShow: widget.isLoading),
AppCustomChipWidget(
icon: AppAssets.appointment_time_icon,
labelText: DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(widget.patientAppointmentHistoryResponseModel.appointmentDate), false)),
labelText: widget.isLoading
? "Cardiology"
: DateUtil.formatDateToTimeLang(DateUtil.convertStringToDate(widget.patientAppointmentHistoryResponseModel.appointmentDate), false))
.toShimmer2(isShow: widget.isLoading),
],
),
],
@ -165,12 +177,12 @@ class _AppointmentCardState extends State<AppointmentCard> {
Expanded(
flex: 6,
child: AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel)
? getArrivedAppointmentButton()
? getArrivedAppointmentButton().toShimmer2(isShow: widget.isLoading)
: CustomButton(
text: AppointmentType.getNextActionText(widget.patientAppointmentHistoryResponseModel.nextAction),
onPressed: () {
Navigator.of(context)
.push(FadePage(
.push(CustomPageRoute(
page: AppointmentDetailsPage(patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel),
))
.then((val) {
@ -188,8 +200,8 @@ class _AppointmentCardState extends State<AppointmentCard> {
height: 40.h,
icon: AppointmentType.getNextActionIcon(widget.patientAppointmentHistoryResponseModel.nextAction),
iconColor: AppointmentType.getNextActionTextColor(widget.patientAppointmentHistoryResponseModel.nextAction),
iconSize: 14.h,
),
iconSize: 15.h,
).toShimmer2(isShow: widget.isLoading),
),
SizedBox(width: 8.h),
Expanded(
@ -210,10 +222,10 @@ class _AppointmentCardState extends State<AppointmentCard> {
fit: BoxFit.contain,
),
),
).onPress(() {
).toShimmer2(isShow: widget.isLoading).onPress(() {
Navigator.of(context)
.push(
FadePage(
CustomPageRoute(
page: AppointmentDetailsPage(patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel),
),
)

@ -19,6 +19,7 @@ import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:barcode_scan2/barcode_scan2.dart';
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
import 'package:hmg_patient_app_new/widgets/nfc/nfc_reader_sheet.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
class AppointmentCheckinBottomSheet extends StatelessWidget {
@ -51,7 +52,7 @@ class AppointmentCheckinBottomSheet extends StatelessWidget {
// navigationService: myAppointmentsViewModel.navigationService,
// appState: myAppointmentsViewModel.appState,
// );
locationUtils.getCurrentLocation(callBack: (value) {
locationUtils.getCurrentLocation(onSuccess: (value) {
projectDetailListModel = Utils.getProjectDetailObj(_appState, patientAppointmentHistoryResponseModel.projectID);
double dist = Utils.distance(value.latitude, value.longitude, double.parse(projectDetailListModel.latitude!), double.parse(projectDetailListModel.longitude!)).ceilToDouble() * 1000;
print(dist);
@ -110,13 +111,15 @@ class AppointmentCheckinBottomSheet extends StatelessWidget {
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
title.toText16(isBold: true, color: AppColors.textColor),
subTitle.toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor),
],
),
),
Utils.buildSvgWithAssets(
icon: AppAssets.forward_arrow_icon,
iconColor: AppColors.blackColor,
@ -144,12 +147,12 @@ class AppointmentCheckinBottomSheet extends StatelessWidget {
Navigator.of(context).pop();
Navigator.pushAndRemoveUntil(
context,
FadePage(
CustomPageRoute(
page: LandingNavigation(),
),
(r) => false);
Navigator.of(context).push(
FadePage(page: MyAppointmentsPage()),
CustomPageRoute(page: MyAppointmentsPage()),
);
}, isFullScreen: false);
},

@ -93,7 +93,7 @@ class HospitalBottomSheetBody extends StatelessWidget {
?.hmcDoctorList?[index];
return HospitalListItem(
hospitalData: hospital,
isLocationEnabled: appointmentsViewModel.getLocationStatus(),
isLocationEnabled: appointmentsViewModel.isLocationEnabled(),
).onPress(() {
regionalViewModel.setHospitalModel(hospital);
regionalViewModel.setBottomSheetState(AppointmentViaRegionState.CLINIC_SELECTION);

@ -65,7 +65,7 @@ class _SavedLogin extends State<SavedLogin> {
body: SafeArea(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 24.h),
child: Column(
child: appState.getSelectDeviceByImeiRespModelElement != null ? Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Spacer(flex: 2),
@ -306,7 +306,7 @@ class _SavedLogin extends State<SavedLogin> {
),
const SizedBox(height: 20),
],
),
) : SizedBox.shrink(),
),
),
);

@ -14,15 +14,14 @@ import 'package:hmg_patient_app_new/features/my_appointments/appointment_via_reg
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/doctor_list_api_response.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/appointments/widgets/faculity_selection/facility_type_selection_widget.dart';
import 'package:hmg_patient_app_new/presentation/appointments/widgets/region_bottomsheet/region_list_widget.dart'
show RegionBottomSheetBody;
import 'package:hmg_patient_app_new/presentation/appointments/widgets/region_bottomsheet/region_list_widget.dart' show RegionBottomSheetBody;
import 'package:hmg_patient_app_new/presentation/book_appointment/search_doctor_by_name.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/select_clinic_page.dart';
import 'package:hmg_patient_app_new/presentation/lab/collapsing_list_view.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'
show showCommonBottomSheetWithoutHeight;
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart' show showCommonBottomSheetWithoutHeight;
import 'package:hmg_patient_app_new/widgets/custom_tab_bar.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
import 'package:provider/provider.dart';
@ -44,6 +43,7 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
void initState() {
scheduleMicrotask(() {
bookAppointmentsViewModel.initBookAppointmentViewModel();
bookAppointmentsViewModel.getLocation();
});
super.initState();
}
@ -52,13 +52,12 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
Widget build(BuildContext context) {
bookAppointmentsViewModel = Provider.of<BookAppointmentsViewModel>(context, listen: false);
appState = getIt.get<AppState>();
regionalViewModel =
Provider.of<AppointmentViaRegionViewmodel>(context, listen: true);
regionalViewModel = Provider.of<AppointmentViaRegionViewmodel>(context, listen: true);
return Scaffold(
backgroundColor: AppColors.bgScaffoldColor,
body: CollapsingListView(
title: LocaleKeys.bookAppo.tr(context: context),
isLeading: false,
isLeading: Navigator.canPop(context),
child: SingleChildScrollView(
child: Consumer<BookAppointmentsViewModel>(builder: (context, bookAppointmentsVM, child) {
return Column(
@ -125,7 +124,7 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
bookAppointmentsViewModel.setLoadSpecificClinic(false);
bookAppointmentsViewModel.setProjectID(null);
Navigator.of(context).push(
FadePage(
CustomPageRoute(
page: SelectClinicPage(),
),
);
@ -154,7 +153,7 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
).onPress(() {
bookAppointmentsViewModel.setIsDoctorSearchByNameStarted(false);
Navigator.of(context).push(
FadePage(
CustomPageRoute(
page: SearchDoctorByName(),
),
);
@ -198,15 +197,10 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
void openRegionListBottomSheet(BuildContext context) {
regionalViewModel.flush();
// AppointmentViaRegionViewmodel? viewmodel = null;
showCommonBottomSheetWithoutHeight(context,
title: "",
titleWidget: Consumer<AppointmentViaRegionViewmodel>(
builder: (_, data, __) => getTitle(data)),
isDismissible: false,
showCommonBottomSheetWithoutHeight(context, title: "", titleWidget: Consumer<AppointmentViaRegionViewmodel>(builder: (_, data, __) => getTitle(data)), isDismissible: false,
child: Consumer<AppointmentViaRegionViewmodel>(builder: (_, data, __) {
return getRegionalSelectionWidget(data);
}), callBackFunc: () {
});
}), callBackFunc: () {});
}
Widget getRegionalSelectionWidget(AppointmentViaRegionViewmodel data) {
@ -215,7 +209,9 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
}
if (data.bottomSheetState == AppointmentViaRegionState.TYPE_SELECTION) {
bookAppointmentsViewModel.resetFilterList();
return FacilityTypeSelectionWidget(selectedRegion: data.selectedRegionId??"",);
return FacilityTypeSelectionWidget(
selectedRegion: data.selectedRegionId ?? "",
);
}
if (data.bottomSheetState == AppointmentViaRegionState.HOSPITAL_SELECTION) {
return HospitalBottomSheetBody();
@ -225,9 +221,7 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
bookAppointmentsViewModel.setIsClinicsListLoading(true);
bookAppointmentsViewModel.setLoadSpecificClinic(true);
bookAppointmentsViewModel.setProjectID(regionalViewModel.selectedHospital?.hospitalList.first?.mainProjectID.toString());
}
else {
} else {
SizedBox.shrink();
}
return SizedBox.shrink();
@ -237,9 +231,7 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
if (data.selectedRegionId == null) {
return LocaleKeys.selectRegion.tr().toText20(weight: FontWeight.w600);
} else {
return Utils.buildSvgWithAssets(
icon: AppAssets.arrow_back, iconColor: Color(0xff2B353E))
.onPress(() {
return Utils.buildSvgWithAssets(icon: AppAssets.arrow_back, iconColor: Color(0xff2B353E)).onPress(() {
data.handleBackPress();
});
}

@ -16,6 +16,7 @@ import 'package:hmg_patient_app_new/presentation/lab/collapsing_list_view.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/routes/custom_page_route.dart';
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
import 'package:provider/provider.dart';
@ -214,7 +215,7 @@ class _ReviewAppointmentPageState extends State<ReviewAppointmentPage> {
LoadingUtils.hideFullScreenLoader();
Navigator.pushAndRemoveUntil(
context,
FadePage(
CustomPageRoute(
page: LandingNavigation(),
),
(r) => false);

@ -18,6 +18,7 @@ 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:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
import 'package:provider/provider.dart';
@ -122,7 +123,7 @@ class _SearchDoctorByNameState extends State<SearchDoctorByName> {
await bookAppointmentsVM.getDoctorProfile(onSuccess: (dynamic respData) {
LoaderBottomSheet.hideLoader();
Navigator.of(context).push(
FadePage(
CustomPageRoute(
page: DoctorProfilePage(),
),
);

@ -19,6 +19,7 @@ import 'package:hmg_patient_app_new/presentation/book_appointment/widgets/clinic
import 'package:hmg_patient_app_new/presentation/lab/collapsing_list_view.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/input_widget.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
import 'package:provider/provider.dart';
@ -141,13 +142,13 @@ class _SelectClinicPageState extends State<SelectClinicPage> {
bookAppointmentsViewModel.setIsDoctorsListLoading(true);
if (clinic.isLiveCareClinicAndOnline ?? false) {
Navigator.of(context).push(
FadePage(
CustomPageRoute(
page: SelectLivecareClinicPage(),
),
);
} else {
Navigator.of(context).push(
FadePage(
CustomPageRoute(
page: SelectDoctorPage(),
),
);

@ -20,6 +20,7 @@ import 'package:hmg_patient_app_new/theme/colors.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:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
import 'package:provider/provider.dart';
@ -124,7 +125,7 @@ class _SelectDoctorPageState extends State<SelectDoctorPage> {
await bookAppointmentsVM.getDoctorProfile(onSuccess: (dynamic respData) {
LoaderBottomSheet.hideLoader();
Navigator.of(context).push(
FadePage(
CustomPageRoute(
page: DoctorProfilePage(),
),
);

@ -10,6 +10,7 @@ import 'package:hmg_patient_app_new/presentation/book_appointment/select_doctor_
import 'package:hmg_patient_app_new/presentation/lab/collapsing_list_view.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/routes/custom_page_route.dart';
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
class SelectLivecareClinicPage extends StatelessWidget {
@ -122,7 +123,7 @@ class SelectLivecareClinicPage extends StatelessWidget {
onPressed: () {
Navigator.of(context).pop();
Navigator.of(context).push(
FadePage(
CustomPageRoute(
page: SelectDoctorPage(),
),
);

@ -19,6 +19,7 @@ import 'package:hmg_patient_app_new/presentation/home/navigation_screen.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/routes/custom_page_route.dart';
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
import 'package:lottie/lottie.dart';
import 'package:provider/provider.dart';
@ -106,7 +107,7 @@ class _AppointmentCalendarState extends State<AppointmentCalendar> {
),
view: CalendarView.month,
todayHighlightColor: Colors.transparent,
todayTextStyle: TextStyle(color: AppColors.textColor),
todayTextStyle: TextStyle(color: AppColors.textColor, fontWeight: FontWeight.bold),
selectionDecoration: ShapeDecoration(
color: AppColors.transparent,
shape: SmoothRectangleBorder(
@ -151,8 +152,8 @@ class _AppointmentCalendarState extends State<AppointmentCalendar> {
child: Wrap(
direction: Axis.horizontal,
alignment: WrapAlignment.start,
spacing: 8.h,
runSpacing: 8.h,
spacing: 6.h,
runSpacing: 6.h,
children: List.generate(
dayEvents.length, // Generate a large number of items to ensure scrolling
(index) => TimeSlotChip(
@ -177,7 +178,7 @@ class _AppointmentCalendarState extends State<AppointmentCalendar> {
bookAppointmentsViewModel.setSelectedAppointmentDateTime(selectedDate, selectedTime);
Navigator.of(context).pop();
Navigator.of(context).push(
FadePage(
CustomPageRoute(
page: ReviewAppointmentPage(),
),
);
@ -216,7 +217,7 @@ class _AppointmentCalendarState extends State<AppointmentCalendar> {
Navigator.of(context).pop();
Navigator.pushAndRemoveUntil(
context,
FadePage(
CustomPageRoute(
page: LandingNavigation(),
),
(r) => false);
@ -320,7 +321,7 @@ class TimeSlotChip extends StatelessWidget {
return GestureDetector(
onTap: onTap,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 18.h, vertical: 8.h),
padding: EdgeInsets.symmetric(horizontal: 14.h, vertical: 8.h),
decoration: ShapeDecoration(
color: AppColors.whiteColor,
shape: SmoothRectangleBorder(

@ -13,6 +13,7 @@ import 'package:hmg_patient_app_new/presentation/habib_wallet/recharge_wallet_pa
import 'package:hmg_patient_app_new/presentation/lab/collapsing_list_view.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/routes/custom_page_route.dart';
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
import 'package:provider/provider.dart';
@ -84,7 +85,7 @@ class _HabibWalletState extends State<HabibWalletPage> {
text: "Recharge".needTranslation,
onPressed: () {
Navigator.of(context).push(
FadePage(
CustomPageRoute(
page: RechargeWalletPage(),
),
);

@ -80,7 +80,7 @@ class LandingPageData {
),
ServiceCardData(
serviceName: "lab_results",
icon: AppAssets.lab_result_icon,
icon: AppAssets.home_lab_result_icon,
title: "My Lab",
subtitle: "Results",
backgroundColor: AppColors.whiteColor,
@ -90,7 +90,7 @@ class LandingPageData {
),
ServiceCardData(
serviceName: "radiology_results",
icon: AppAssets.lab_result_icon,
icon: AppAssets.home_lab_result_icon,
title: "My Radiology",
subtitle: "Results",
backgroundColor: AppColors.whiteColor,

@ -3,6 +3,7 @@ import 'dart:async';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
import 'package:flutter_swiper_view/flutter_swiper_view.dart';
import 'package:get_it/get_it.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
@ -15,9 +16,12 @@ import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart';
import 'package:hmg_patient_app_new/features/habib_wallet/habib_wallet_view_model.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/features/prescriptions/prescriptions_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/appointments/my_appointments_page.dart';
import 'package:hmg_patient_app_new/presentation/appointments/widgets/appointment_card.dart';
import 'package:hmg_patient_app_new/presentation/authentication/quick_login.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/book_appointment_page.dart';
import 'package:hmg_patient_app_new/presentation/home/data/landing_page_data.dart';
@ -34,6 +38,7 @@ 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/custom_tab_bar.dart' show CustomTabBar;
import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:hmg_patient_app_new/widgets/routes/spring_page_route_builder.dart';
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
import 'package:provider/provider.dart';
@ -55,6 +60,8 @@ class _LandingPageState extends State<LandingPage> {
late PrescriptionsViewModel prescriptionsViewModel;
final CacheService cacheService = GetIt.instance<CacheService>();
final SwiperController _controller = SwiperController();
@override
void initState() {
authVM = context.read<AuthenticationViewModel>();
@ -87,7 +94,7 @@ class _LandingPageState extends State<LandingPage> {
return Scaffold(
backgroundColor: AppColors.bgScaffoldColor,
body: SingleChildScrollView(
padding: EdgeInsets.only(top: kToolbarHeight + 12.h, bottom: 24),
padding: EdgeInsets.only(top: kToolbarHeight + 0.h, bottom: 24),
child: Column(
spacing: 16.h,
children: [
@ -123,7 +130,7 @@ class _LandingPageState extends State<LandingPage> {
children: [
Utils.buildSvgWithAssets(icon: AppAssets.bell, height: 20, width: 20).onPress(() {
Navigator.of(context).push(
FadePage(
CustomPageRoute(
page: MedicalFilePage(),
// page: LoginScreen(),
),
@ -131,7 +138,7 @@ class _LandingPageState extends State<LandingPage> {
}),
Utils.buildSvgWithAssets(icon: AppAssets.search_icon, height: 20, width: 20).onPress(() {
Navigator.of(context).push(
FadePage(
CustomPageRoute(
page: MedicalFilePage(),
// page: LoginScreen(),
),
@ -139,7 +146,7 @@ class _LandingPageState extends State<LandingPage> {
}),
Utils.buildSvgWithAssets(icon: AppAssets.contact_icon, height: 20, width: 20).onPress(() {
Navigator.of(context).push(
FadePage(
CustomPageRoute(
page: MedicalFilePage(),
// page: LoginScreen(),
),
@ -152,25 +159,95 @@ class _LandingPageState extends State<LandingPage> {
appState.isAuthenticated
? Column(
children: [
Container(
width: double.infinity,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 24,
SizedBox(height: 12.h),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"Appointments & Visits".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),
],
),
],
).paddingSymmetrical(24.h, 0.h).onPress(() {
Navigator.of(context).push(
CustomPageRoute(
page: MyAppointmentsPage(),
),
);
}),
SizedBox(height: 12.h),
Consumer<MyAppointmentsViewModel>(builder: (context, myAppointmentsVM, child) {
return myAppointmentsVM.isMyAppointmentsLoading
? Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true),
child: AppointmentCard(
patientAppointmentHistoryResponseModel: PatientAppointmentHistoryResponseModel(),
myAppointmentsViewModel: myAppointmentsViewModel,
isLoading: true,
isFromHomePage: true,
),
).paddingSymmetrical(24.h, 0.h)
: myAppointmentsVM.patientAppointmentsHistoryList.isNotEmpty
? myAppointmentsVM.patientAppointmentsHistoryList.length == 1
? Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true),
child: AppointmentCard(
patientAppointmentHistoryResponseModel: myAppointmentsVM.patientAppointmentsHistoryList.first,
myAppointmentsViewModel: myAppointmentsViewModel,
isLoading: false,
isFromHomePage: true,
),
).paddingSymmetrical(24.h, 0.h)
: Swiper(
itemCount: myAppointmentsVM.isMyAppointmentsLoading
? 3
: myAppointmentsVM.patientAppointmentsHistoryList.length < 3
? myAppointmentsVM.patientAppointmentsHistoryList.length
: 3,
layout: SwiperLayout.STACK,
loop: true,
itemWidth: MediaQuery.of(context).size.width - 72,
indicatorLayout: PageIndicatorLayout.COLOR,
axisDirection: AxisDirection.right,
controller: _controller,
itemHeight: 210 + 25,
pagination: const SwiperPagination(
alignment: Alignment.bottomCenter,
margin: EdgeInsets.only(top: 210 + 8 + 24),
builder: DotSwiperPaginationBuilder(color: Color(0xffD9D9D9), activeColor: AppColors.blackBgColor),
),
itemBuilder: (BuildContext context, int index) {
return Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true),
child: AppointmentCard(
patientAppointmentHistoryResponseModel: myAppointmentsVM.patientAppointmentsHistoryList[index],
myAppointmentsViewModel: myAppointmentsViewModel,
isLoading: false,
isFromHomePage: true,
),
);
},
)
: Container(
width: double.infinity,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24, hasShadow: true),
child: Padding(
padding: EdgeInsets.all(12.h),
child: Column(
children: [
Utils.buildSvgWithAssets(icon: AppAssets.home_calendar_icon, width: 32.h, height: 32.h),
SizedBox(height: 12.h),
"You do not have any upcoming appointment. Please book an appointment".toText12(isCenter: true),
"You do not have any upcoming appointment. Please book an appointment".needTranslation.toText12(isCenter: true),
SizedBox(height: 12.h),
CustomButton(
text: LocaleKeys.bookAppo.tr(context: context),
onPressed: () {
Navigator.of(context).push(
FadePage(
CustomPageRoute(
page: BookAppointmentPage(),
),
);
@ -189,7 +266,8 @@ class _LandingPageState extends State<LandingPage> {
],
),
),
).paddingSymmetrical(24.h, 0.h),
).paddingSymmetrical(24.h, 0.h);
}),
SizedBox(height: 12.h),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -205,7 +283,7 @@ class _LandingPageState extends State<LandingPage> {
],
).paddingSymmetrical(24.h, 0.h).onPress(() {
Navigator.of(context).push(
FadePage(
CustomPageRoute(
page: MedicalFilePage(),
),
);

@ -8,6 +8,7 @@ import 'package:hmg_patient_app_new/features/habib_wallet/habib_wallet_view_mode
import 'package:hmg_patient_app_new/presentation/habib_wallet/habib_wallet_page.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
import 'package:provider/provider.dart';
@ -98,7 +99,7 @@ class HabibWalletCard extends StatelessWidget {
],
).onPress(() {
Navigator.of(context).push(
FadePage(
CustomPageRoute(
page: HabibWalletPage(),
),
);

@ -7,6 +7,7 @@ import 'package:hmg_patient_app_new/presentation/insurance/insurance_home_page.d
import 'package:hmg_patient_app_new/presentation/lab/lab_orders_page.dart';
import 'package:hmg_patient_app_new/presentation/medical_file/patient_sickleaves_list_page.dart';
import 'package:hmg_patient_app_new/presentation/prescriptions/prescriptions_list_page.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
import '../../../core/utils/utils.dart';
@ -61,28 +62,28 @@ class SmallServiceCard extends StatelessWidget {
switch (serviceName) {
case "lab_results":
Navigator.of(context).push(
FadePage(
CustomPageRoute(
page: LabOrdersPage(),
),
);
break;
case "radiology_results":
Navigator.of(context).push(
FadePage(
CustomPageRoute(
page: RadiologyOrdersPage(),
),
);
break;
case "prescriptions":
Navigator.of(context).push(
FadePage(
CustomPageRoute(
page: PrescriptionsListPage(),
),
);
break;
case "insurance_update":
Navigator.of(context).push(
FadePage(
CustomPageRoute(
page: InsuranceHomePage(),
),
);
@ -90,7 +91,7 @@ class SmallServiceCard extends StatelessWidget {
case "my_doctors":
Navigator.of(context).push(
FadePage(
CustomPageRoute(
page: MyDoctorsPage(),
),
);
@ -98,7 +99,7 @@ class SmallServiceCard extends StatelessWidget {
case "sick_leaves":
Navigator.of(context).push(
FadePage(
CustomPageRoute(
page: PatientSickleavesListPage(),
),
);

@ -37,8 +37,9 @@ class WelcomeWidget extends StatelessWidget {
Row(
spacing: 4.h,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
name.toText16(weight: FontWeight.w500, textOverflow: TextOverflow.ellipsis, maxlines: 1, height: 1).expanded,
Flexible(child: name.toText16(weight: FontWeight.w500, textOverflow: TextOverflow.ellipsis, maxlines: 1, height: 1)),
const Icon(Icons.keyboard_arrow_down, size: 20, color: Colors.black),
],
),

@ -40,6 +40,7 @@ import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
import 'package:hmg_patient_app_new/widgets/custom_tab_bar.dart';
import 'package:hmg_patient_app_new/widgets/input_widget.dart';
import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:hmg_patient_app_new/widgets/shimmer/movies_shimmer_widget.dart';
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
import 'package:provider/provider.dart';
@ -314,7 +315,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
],
).paddingSymmetrical(24.h, 0.h).onPress(() {
Navigator.of(context).push(
FadePage(
CustomPageRoute(
page: MyAppointmentsPage(),
),
);
@ -415,8 +416,8 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
children: [
Image.network(
prescriptionVM.patientPrescriptionOrders[index].doctorImageURL!,
width: 63.h,
height: 63.h,
width: 40.h,
height: 40.h,
fit: BoxFit.fill,
).circle(100),
SizedBox(width: 16.h),
@ -441,13 +442,13 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
],
),
),
SizedBox(width: 40.h),
// SizedBox(width: 40.h),
Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon, width: 15.h, height: 15.h, fit: BoxFit.contain, iconColor: AppColors.textColor),
],
).onPress(() {
prescriptionVM.setPrescriptionsDetailsLoading();
Navigator.of(context).push(
FadePage(
CustomPageRoute(
page: PrescriptionDetailPage(prescriptionsResponseModel: prescriptionVM.patientPrescriptionOrders[index]),
),
);
@ -468,7 +469,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
text: "All Prescriptions".needTranslation,
onPressed: () {
Navigator.of(context).push(
FadePage(
CustomPageRoute(
page: PrescriptionsListPage(),
),
);
@ -526,7 +527,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
myAppointmentsViewModel.setIsPatientMyDoctorsLoading(true);
myAppointmentsViewModel.getPatientMyDoctors();
Navigator.of(context).push(
FadePage(
CustomPageRoute(
page: MyDoctorsPage(),
),
);
@ -631,7 +632,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
iconSize: 40.h,
).onPress(() {
Navigator.of(context).push(
FadePage(
CustomPageRoute(
page: VaccineListPage(),
),
);
@ -673,7 +674,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
iconSize: 36.h)
.onPress(() {
Navigator.of(context).push(
FadePage(
CustomPageRoute(
page: InsuranceHomePage(),
),
);
@ -747,7 +748,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
medicalFileViewModel.setIsPatientMedicalReportsLoading(true);
medicalFileViewModel.getPatientMedicalReportList();
Navigator.of(context).push(
FadePage(
CustomPageRoute(
page: MedicalReportsPage(),
),
);
@ -761,7 +762,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
iconSize: 40.h,
).onPress(() {
Navigator.of(context).push(
FadePage(
CustomPageRoute(
page: PatientSickleavesListPage(),
),
);

@ -13,6 +13,7 @@ import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/appointments/appointment_details_page.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
class MedicalFileAppointmentCard extends StatelessWidget {
@ -86,7 +87,7 @@ class MedicalFileAppointmentCard extends StatelessWidget {
text: AppointmentType.getNextActionText(patientAppointmentHistoryResponseModel.nextAction),
onPressed: () {
Navigator.of(context)
.push(FadePage(
.push(CustomPageRoute(
page: AppointmentDetailsPage(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel),
))
.then((val) {
@ -129,7 +130,7 @@ class MedicalFileAppointmentCard extends StatelessWidget {
).toShimmer2(isShow: myAppointmentsViewModel.isMyAppointmentsLoading).onPress(() {
Navigator.of(context)
.push(
FadePage(
CustomPageRoute(
page: AppointmentDetailsPage(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel),
),
)

@ -17,6 +17,7 @@ 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';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
import 'package:open_filex/open_filex.dart';
import 'package:provider/provider.dart';
@ -147,7 +148,7 @@ class PatientSickLeaveCard extends StatelessWidget {
),
).toShimmer2(isShow: isLoading).onPress(() {
Navigator.of(context).push(
FadePage(
CustomPageRoute(
page: PatientSickleavesListPage(),
),
);

@ -15,6 +15,7 @@ import 'package:hmg_patient_app_new/presentation/lab/collapsing_list_view.dart';
import 'package:hmg_patient_app_new/presentation/prescriptions/prescription_detail_page.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:hmg_patient_app_new/widgets/shimmer/movies_shimmer_widget.dart';
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
import 'package:provider/provider.dart';
@ -258,7 +259,7 @@ class _PrescriptionsListPageState extends State<PrescriptionsListPage> {
).onPress(() {
model.setPrescriptionsDetailsLoading();
Navigator.of(context).push(
FadePage(
CustomPageRoute(
page: PrescriptionDetailPage(prescriptionsResponseModel: prescription),
),
);

@ -115,7 +115,7 @@ class _ProfileSettingsState extends State<ProfileSettings> {
iconSize: 24.h,
iconColor: AppColors.infoColor,
textColor: AppColors.infoColor,
text: "Recharge",
text: "Recharge".needTranslation,
borderWidth: 0.h,
fontWeight: FontWeight.w500,
borderColor: Colors.transparent,

@ -12,8 +12,11 @@ import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/features/lab/lab_view_model.dart';
import 'package:hmg_patient_app_new/presentation/lab/collapsing_list_view.dart';
import 'package:hmg_patient_app_new/presentation/radiology/radiology_result_page.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart';
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'package:hmg_patient_app_new/widgets/shimmer/movies_shimmer_widget.dart';
import 'package:provider/provider.dart';
@ -49,10 +52,11 @@ class _RadiologyOrdersPageState extends State<RadiologyOrdersPage> {
child: SingleChildScrollView(
child: Consumer<RadiologyViewModel>(
builder: (context, model, child) {
return Column(
return Padding(
padding: EdgeInsets.symmetric(horizontal: 24.h),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 16.h),
// Expandable list
ListView.builder(
shrinkWrap: true,
@ -60,9 +64,7 @@ class _RadiologyOrdersPageState extends State<RadiologyOrdersPage> {
itemCount: model.isRadiologyOrdersLoading ? 5 : model.patientRadiologyOrders.length,
itemBuilder: (context, index) {
final isExpanded = expandedIndex == index;
return model.isRadiologyOrdersLoading
? const MoviesShimmerWidget()
: AnimationConfiguration.staggeredList(
return AnimationConfiguration.staggeredList(
position: index,
duration: const Duration(milliseconds: 500),
child: SlideAnimation(
@ -87,71 +89,52 @@ class _RadiologyOrdersPageState extends State<RadiologyOrdersPage> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
CustomButton(
text: LocaleKeys.resultsAvailable.tr(context: context),
onPressed: () {},
AppCustomChipWidget(
labelText: LocaleKeys.resultsAvailable.tr(context: context),
backgroundColor: AppColors.successColor.withOpacity(0.15),
borderColor: AppColors.successColor.withOpacity(0.01),
textColor: AppColors.successColor,
fontSize: 10,
fontWeight: FontWeight.w500,
borderRadius: 8,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 30.h,
),
Icon(isExpanded ? Icons.expand_less : Icons.expand_more),
],
),
).toShimmer2(isShow: model.isRadiologyOrdersLoading, width: 100),
SizedBox(height: 8.h),
Row(
children: [
Image.network(
model.patientRadiologyOrders[index].doctorImageURL!,
model.isRadiologyOrdersLoading
? "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png"
: model.patientRadiologyOrders[index].doctorImageURL!,
width: 24.h,
height: 24.h,
fit: BoxFit.fill,
).circle(100),
).circle(100).toShimmer2(isShow: model.isRadiologyOrdersLoading),
SizedBox(width: 4.h),
model.patientRadiologyOrders[index].doctorName!.toText16(isBold: true)
(model.isRadiologyOrdersLoading ? "Dr John Smith" : model.patientRadiologyOrders[index].doctorName!)
.toText16(isBold: true)
.toShimmer2(isShow: model.isRadiologyOrdersLoading)
],
),
SizedBox(height: 8.h),
Row(
Wrap(
direction: Axis.horizontal,
spacing: 3.h,
runSpacing: 4.h,
children: [
CustomButton(
text: DateUtil.formatDateToDate(DateUtil.convertStringToDate(model.patientRadiologyOrders[index].orderDate), false),
onPressed: () {},
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 12,
fontWeight: FontWeight.w500,
borderRadius: 8,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 24.h,
),
SizedBox(width: 8.h),
CustomButton(
text: model.patientRadiologyOrders[index].clinicDescription!,
onPressed: () {},
backgroundColor: AppColors.greyColor,
borderColor: AppColors.greyColor,
textColor: AppColors.blackColor,
fontSize: 12,
fontWeight: FontWeight.w500,
borderRadius: 8,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 24.h,
),
AppCustomChipWidget(
icon: AppAssets.doctor_calendar_icon,
labelText: model.isRadiologyOrdersLoading ? "01 Jan 2025" : DateUtil.formatDateToDate(model.patientRadiologyOrders[index].orderDate!, false),
).toShimmer2(isShow: model.isRadiologyOrdersLoading),
AppCustomChipWidget(
labelText: model.isRadiologyOrdersLoading ? "01 Jan 2025" : model.patientRadiologyOrders[index].clinicDescription!,
).toShimmer2(isShow: model.isRadiologyOrdersLoading),
// AppCustomChipWidget(labelText: "").toShimmer2(isShow: model.isRadiologyOrdersLoading, width: 16.h),
// AppCustomChipWidget(labelText: "").toShimmer2(isShow: model.isRadiologyOrdersLoading, width: 16.h),
],
),
],
),
),
AnimatedCrossFade(
model.isRadiologyOrdersLoading
? SizedBox.shrink()
: AnimatedCrossFade(
firstChild: SizedBox.shrink(),
secondChild: Padding(
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 8.h),
@ -171,7 +154,13 @@ class _RadiologyOrdersPageState extends State<RadiologyOrdersPage> {
iconColor: AppColors.primaryRedColor,
iconSize: 16.h,
text: LocaleKeys.viewReport.tr(context: context),
onPressed: () {},
onPressed: () {
Navigator.of(context).push(
CustomPageRoute(
page: RadiologyResultPage(patientRadiologyResponseModel: model.patientRadiologyOrders[index]),
),
);
},
backgroundColor: AppColors.secondaryLightRedColor,
borderColor: AppColors.secondaryLightRedColor,
textColor: AppColors.primaryRedColor,
@ -199,6 +188,7 @@ class _RadiologyOrdersPageState extends State<RadiologyOrdersPage> {
},
),
],
),
);
},
),

@ -0,0 +1,162 @@
import 'dart:async';
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/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/radiology/models/resp_models/patient_radiology_response_model.dart';
import 'package:hmg_patient_app_new/features/radiology/radiology_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/lab/collapsing_list_view.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/loader/bottomsheet_loader.dart';
import 'package:open_filex/open_filex.dart';
import 'package:provider/provider.dart';
import 'package:url_launcher/url_launcher.dart';
class RadiologyResultPage extends StatefulWidget {
RadiologyResultPage({super.key, required this.patientRadiologyResponseModel});
PatientRadiologyResponseModel patientRadiologyResponseModel;
@override
State<RadiologyResultPage> createState() => _RadiologyResultPageState();
}
class _RadiologyResultPageState extends State<RadiologyResultPage> {
late RadiologyViewModel radiologyViewModel;
@override
void initState() {
scheduleMicrotask(() {
radiologyViewModel.getRadiologyImage(patientRadiologyResponseModel: widget.patientRadiologyResponseModel);
});
super.initState();
}
@override
Widget build(BuildContext context) {
radiologyViewModel = Provider.of<RadiologyViewModel>(context);
AppState _appState = getIt.get<AppState>();
return Scaffold(
backgroundColor: AppColors.bgScaffoldColor,
body: Column(
children: [
Expanded(
child: CollapsingListView(
title: "Radiology Result".needTranslation,
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 24.h),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 24.h),
Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 20.h,
hasShadow: true,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 16.h),
widget.patientRadiologyResponseModel.description!.toText16(isBold: true),
SizedBox(height: 8.h),
widget.patientRadiologyResponseModel.reportData!.trim().toText12(isBold: true, color: AppColors.textColorLight),
SizedBox(height: 16.h),
CustomButton(
text: "View Radiology Image".needTranslation,
onPressed: () async {
if (radiologyViewModel.radiologyImageURL.isNotEmpty) {
Uri uri = Uri.parse(radiologyViewModel.radiologyImageURL);
launchUrl(uri, mode: LaunchMode.platformDefault, webOnlyWindowName: "");
} else {
Utils.showToast("Radiology image not available".needTranslation);
}
},
backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedColor,
textColor: AppColors.whiteColor,
fontSize: 14,
fontWeight: FontWeight.w500,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 40.h,
icon: AppAssets.download,
iconColor: AppColors.whiteColor,
iconSize: 20.h,
),
SizedBox(height: 16.h),
],
).paddingSymmetrical(16.h, 0.h),
),
SizedBox(height: 24.h),
],
),
),
),
),
),
Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 24.h,
hasShadow: true,
),
child: CustomButton(
text: "Download report".needTranslation,
onPressed: () async {
LoaderBottomSheet.showLoader();
await radiologyViewModel.getRadiologyPDF(patientRadiologyResponseModel: widget.patientRadiologyResponseModel, authenticatedUser: _appState.getAuthenticatedUser()!, onError: (err) {
LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight(
context,
child: Utils.getErrorWidget(loadingText: err),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
}).then((val) async {
LoaderBottomSheet.hideLoader();
if (radiologyViewModel.patientRadiologyReportPDFBase64.isNotEmpty) {
String path = await Utils.createFileFromString(radiologyViewModel.patientRadiologyReportPDFBase64, "pdf");
try {
OpenFilex.open(path);
} catch (ex) {
showCommonBottomSheetWithoutHeight(
context,
child: Utils.getErrorWidget(loadingText: "Cannot open file".needTranslation),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
}
}
});
},
backgroundColor: AppColors.successColor,
borderColor: AppColors.successColor,
textColor: AppColors.whiteColor,
fontSize: 16,
fontWeight: FontWeight.w500,
borderRadius: 12,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
height: 45.h,
icon: AppAssets.download,
iconColor: AppColors.whiteColor,
iconSize: 20.h,
).paddingSymmetrical(24.h, 24.h),
),
],
),
);
}
}

@ -21,6 +21,7 @@ import 'package:provider/provider.dart';
import 'core/cache_consts.dart';
import 'core/utils/local_notifications.dart';
import 'core/utils/push_notification_handler.dart';
import 'widgets/routes/custom_page_route.dart';
class SplashPage extends StatefulWidget {
@override
@ -42,7 +43,7 @@ class _SplashScreenState extends State<SplashPage> {
Timer(Duration(seconds: 2, milliseconds: 500), () async {
LocalNotification.init(onNotificationClick: (payload) {});
Navigator.of(context).pushReplacement(
FadePage(
CustomPageRoute(
page: LandingNavigation(),
// page: LoginScreen(),
),

@ -83,6 +83,8 @@ dependencies:
family_bottom_sheet: ^0.1.0
location: ^8.0.1
gms_check: ^1.0.4
huawei_location: ^6.14.2+301
dev_dependencies:
flutter_test:

Loading…
Cancel
Save