login flow inprogress

pull/14/head
Sultan khan 2 months ago
parent 61d10068ca
commit ba2c8327fe

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

@ -806,5 +806,10 @@
"loginBy": "تسجيل الدخول بواسطة", "loginBy": "تسجيل الدخول بواسطة",
"loginByOTP": "تسجيل الدخول بواسطة OTP", "loginByOTP": "تسجيل الدخول بواسطة OTP",
"guest": "زائر", "guest": "زائر",
"switchAccount": "تبديل الحساب" "switchAccount": "تبديل الحساب",
"lastLoginBy":"آخر تسجيل دخول بواسطة",
"allSet": "جاهز! الآن يمكنك تسجيل الدخول باستخدام Face ID / Biometric أو البصمة",
"enableQuickLogin":"تمكين تسجيل الدخول السريع",
"enableMsg":"تمكين تسجيل الدخول السريع سيسمح بالتحقق من خلال Face ID / Biometric الخاص بجهازك الحالي",
"notNow": "ليس الآن"
} }

@ -802,5 +802,10 @@
"loginBy": "Login By", "loginBy": "Login By",
"loginByOTP": "Login By OTP", "loginByOTP": "Login By OTP",
"guest": "Guest", "guest": "Guest",
"switchAccount": "Switch Account" "switchAccount": "Switch Account",
"lastloginBy": "Last login by",
"allSet": "All Set! Now you can login with Face ID or Biometric",
"enableQuickLogin": "Enable Quick Login",
"enableMsg": "Enabling the quick login will verify through your existing device Face ID / Biometric",
"notNow": "Not Now"
} }

@ -75,6 +75,8 @@ class AppAssets {
static const String insurance = '$svgBasePath/insurance.svg'; static const String insurance = '$svgBasePath/insurance.svg';
static const String requests = '$svgBasePath/requests.svg'; static const String requests = '$svgBasePath/requests.svg';
static const String more = '$svgBasePath/more.svg'; static const String more = '$svgBasePath/more.svg';
static const String bell = '$svgBasePath/bell.svg';
//bottom navigation// //bottom navigation//
static const String homeBottom = '$svgBasePath/home_bottom.svg'; static const String homeBottom = '$svgBasePath/home_bottom.svg';
@ -88,12 +90,13 @@ class AppAssets {
static const String hmg_logo = '$pngBasePath/hmg_logo.png'; static const String hmg_logo = '$pngBasePath/hmg_logo.png';
static const String livecare_service = '$pngBasePath/livecare_service.png'; static const String livecare_service = '$pngBasePath/livecare_service.png';
static const String male_img = '$pngBasePath/male_img.png'; static const String male_img = '$pngBasePath/male_img.png';
static const String femaleImg = '$pngBasePath/female_img.png';
static const String apple_pay = '$pngBasePath/Apple_Pay.png'; static const String apple_pay = '$pngBasePath/Apple_Pay.png';
static const String mada = '$pngBasePath/Mada.png'; static const String mada = '$pngBasePath/Mada.png';
static const String Mastercard = '$pngBasePath/Mastercard.png'; static const String Mastercard = '$pngBasePath/Mastercard.png';
static const String tamara_en = '$pngBasePath/tamara_en.png'; static const String tamara_en = '$pngBasePath/tamara_en.png';
static const String visa = '$pngBasePath/visa.png'; static const String visa = '$pngBasePath/visa.png';
static const String lockIcon = '$pngBasePath/lock-icon.png';
} }
class AppAnimations { class AppAnimations {

@ -33,6 +33,7 @@ class AppState {
if (isFamily) { if (isFamily) {
_authenticatedChildUser = authenticatedUser; _authenticatedChildUser = authenticatedUser;
} else { } else {
setIsAuthenticated = true;
_authenticatedRootUser = authenticatedUser; _authenticatedRootUser = authenticatedUser;
} }
} }
@ -75,7 +76,7 @@ class AppState {
set setSessionId(v) => sessionId = v; set setSessionId(v) => sessionId = v;
bool isAuthenticated = true; bool isAuthenticated = false;
set setIsAuthenticated(v) => isAuthenticated = v; set setIsAuthenticated(v) => isAuthenticated = v;

@ -21,8 +21,10 @@ import 'package:hmg_patient_app_new/services/cache_service.dart';
import 'package:hmg_patient_app_new/services/dialog_service.dart'; import 'package:hmg_patient_app_new/services/dialog_service.dart';
import 'package:hmg_patient_app_new/services/error_handler_service.dart'; import 'package:hmg_patient_app_new/services/error_handler_service.dart';
import 'package:hmg_patient_app_new/services/firebase_service.dart'; import 'package:hmg_patient_app_new/services/firebase_service.dart';
import 'package:hmg_patient_app_new/services/localauth_service.dart';
import 'package:hmg_patient_app_new/services/logger_service.dart'; import 'package:hmg_patient_app_new/services/logger_service.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart'; import 'package:hmg_patient_app_new/services/navigation_service.dart';
import 'package:local_auth/local_auth.dart';
import 'package:logger/web.dart'; import 'package:logger/web.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
@ -49,6 +51,8 @@ class AppDependencies {
)); ));
getIt.registerLazySingleton<NavigationService>(() => NavigationService()); getIt.registerLazySingleton<NavigationService>(() => NavigationService());
getIt.registerLazySingleton<LocalAuthentication>(() => LocalAuthentication());
getIt.registerLazySingleton<GAnalytics>(() => GAnalytics()); getIt.registerLazySingleton<GAnalytics>(() => GAnalytics());
getIt.registerLazySingleton<AppState>(() => AppState(navigationService: getIt())); getIt.registerLazySingleton<AppState>(() => AppState(navigationService: getIt()));
getIt.registerLazySingleton<LocationUtils>(() => LocationUtils( getIt.registerLazySingleton<LocationUtils>(() => LocationUtils(
@ -76,6 +80,7 @@ class AppDependencies {
getIt.registerLazySingleton<RadiologyRepo>(() => RadiologyRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt())); getIt.registerLazySingleton<RadiologyRepo>(() => RadiologyRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
getIt.registerLazySingleton<PrescriptionsRepo>(() => PrescriptionsRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt())); getIt.registerLazySingleton<PrescriptionsRepo>(() => PrescriptionsRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
getIt.registerLazySingleton<InsuranceRepo>(() => InsuranceRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt())); getIt.registerLazySingleton<InsuranceRepo>(() => InsuranceRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
getIt.registerLazySingleton<LocalAuthService>(() => LocalAuthService(loggerService: getIt<LoggerService>(), localAuth: getIt<LocalAuthentication>()));
// ViewModels // ViewModels
// Global/shared VMs LazySingleton // Global/shared VMs LazySingleton
@ -116,6 +121,7 @@ class AppDependencies {
dialogService: getIt(), dialogService: getIt(),
appState: getIt(), appState: getIt(),
errorHandlerService: getIt(), errorHandlerService: getIt(),
localAuthService: getIt()
), ),
); );

@ -32,7 +32,7 @@ enum MaritalStatusTypeEnum { single, married, divorced, widowed }
enum ChipTypeEnum { success, error, alert, info, warning } enum ChipTypeEnum { success, error, alert, info, warning }
enum OTPTypeEnum { sms, whatsapp } enum OTPTypeEnum { sms, whatsapp, faceIDFingerprint }
enum LoginTypeEnum { sms, whatsapp, face, fingerprint } enum LoginTypeEnum { sms, whatsapp, face, fingerprint }
@ -89,6 +89,8 @@ extension OTPTypeEnumExtension on OTPTypeEnum {
return 1; return 1;
case OTPTypeEnum.whatsapp: case OTPTypeEnum.whatsapp:
return 2; return 2;
case OTPTypeEnum.faceIDFingerprint:
return 0;
} }
} }

@ -5,6 +5,11 @@ extension ContextUtils on BuildContext {
double get screenWidth => MediaQuery.of(this).size.width; double get screenWidth => MediaQuery.of(this).size.width;
EdgeInsets get padding => MediaQuery.of(this).padding;
bool get safeInsets => padding.top > 0 || padding.bottom > 0 || padding.left > 0 || padding.right > 0;
ThemeData get theme => Theme.of(this); ThemeData get theme => Theme.of(this);
TextTheme get textTheme => theme.textTheme; TextTheme get textTheme => theme.textTheme;

@ -14,21 +14,21 @@ import 'package:hmg_patient_app_new/features/authentication/models/request_model
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_activation_code_resp_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/authentication/models/resp_models/select_device_by_imei.dart';
import 'package:hmg_patient_app_new/presentation/authentication/login.dart'; import 'package:hmg_patient_app_new/presentation/authentication/login.dart';
import 'package:hmg_patient_app_new/presentation/authentication/saved_login_screen.dart';
import 'package:hmg_patient_app_new/routes/app_routes.dart'; import 'package:hmg_patient_app_new/routes/app_routes.dart';
import 'package:hmg_patient_app_new/services/cache_service.dart'; import 'package:hmg_patient_app_new/services/cache_service.dart';
import 'package:hmg_patient_app_new/services/dialog_service.dart'; import 'package:hmg_patient_app_new/services/dialog_service.dart';
import 'package:hmg_patient_app_new/services/error_handler_service.dart'; import 'package:hmg_patient_app_new/services/error_handler_service.dart';
import 'package:hmg_patient_app_new/services/localauth_service.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart'; import 'package:hmg_patient_app_new/services/navigation_service.dart';
import 'models/resp_models/authenticated_user_resp_model.dart';
class AuthenticationViewModel extends ChangeNotifier { class AuthenticationViewModel extends ChangeNotifier {
final AuthenticationRepo _authenticationRepo; final AuthenticationRepo _authenticationRepo;
final AppState _appState; final AppState _appState;
final ErrorHandlerService _errorHandlerService; final ErrorHandlerService _errorHandlerService;
final DialogService _dialogService; final DialogService _dialogService;
final NavigationService _navigationService; final NavigationService _navigationService;
final LocalAuthService _localAuthService;
AuthenticationViewModel({ AuthenticationViewModel({
required AppState appState, required AppState appState,
required AuthenticationRepo authenticationRepo, required AuthenticationRepo authenticationRepo,
@ -36,11 +36,13 @@ class AuthenticationViewModel extends ChangeNotifier {
required DialogService dialogService, required DialogService dialogService,
required NavigationService navigationService, required NavigationService navigationService,
required CacheService cacheService, required CacheService cacheService,
required LocalAuthService localAuthService,
}) : _navigationService = navigationService, }) : _navigationService = navigationService,
_dialogService = dialogService, _dialogService = dialogService,
_errorHandlerService = errorHandlerService, _errorHandlerService = errorHandlerService,
_appState = appState, _appState = appState,
_authenticationRepo = authenticationRepo; _authenticationRepo = authenticationRepo,
_localAuthService = localAuthService;
final TextEditingController nationalIdController = TextEditingController(), phoneNumberController = TextEditingController(), dobController = TextEditingController(); final TextEditingController nationalIdController = TextEditingController(), phoneNumberController = TextEditingController(), dobController = TextEditingController();
CountryEnum selectedCountrySignup = CountryEnum.saudiArabia; CountryEnum selectedCountrySignup = CountryEnum.saudiArabia;
@ -75,7 +77,7 @@ class AuthenticationViewModel extends ChangeNotifier {
try { try {
LoadingUtils.showFullScreenLoader(); LoadingUtils.showFullScreenLoader();
//TODO: We will remove this delay //TODO: We will remove this delay
await Future.delayed(Duration(seconds: 3)); // await Future.delayed(Duration(seconds: 3));
var data = _appState.getSelectDeviceByImeiRespModelElement; var data = _appState.getSelectDeviceByImeiRespModelElement;
log("Cached IMEI data: ${data?.toJson()}"); log("Cached IMEI data: ${data?.toJson()}");
if (data != null) { if (data != null) {
@ -168,8 +170,8 @@ class AuthenticationViewModel extends ChangeNotifier {
if (savedData != null) { if (savedData != null) {
// TODO: Navigate to SavedLogin when available // TODO: Navigate to SavedLogin when available
_navigationService.pushPage(page: LoginScreen()); //_navigationService.pushPage(page: LoginScreen());
// navigationService.pushPage(page: SavedLogin(savedData)); _navigationService.pushPage(page: SavedLogin());
} }
} catch (e) { } catch (e) {
log("Error handling existing IMEI data: $e"); log("Error handling existing IMEI data: $e");
@ -189,8 +191,8 @@ class AuthenticationViewModel extends ChangeNotifier {
// TODO: Navigate to SavedLogin when available // TODO: Navigate to SavedLogin when available
// SelectDeviceByImeiRespModelElement savedData = // SelectDeviceByImeiRespModelElement savedData =
// SelectDeviceByImeiRespModelElement.fromJson(respData); // SelectDeviceByImeiRespModelElement.fromJson(respData);
// navigationService.pushPage(page: SavedLogin(savedData)); _navigationService.pushPage(page: SavedLogin());
_navigationService.pushPage(page: LoginScreen()); // _navigationService.pushPage(page: LoginScreen());
} else { } else {
LoadingUtils.hideFullScreenLoader(); LoadingUtils.hideFullScreenLoader();
_navigationService.pushPage(page: LoginScreen()); _navigationService.pushPage(page: LoginScreen());
@ -365,6 +367,9 @@ class AuthenticationViewModel extends ChangeNotifier {
// GifLoaderDialogUtils.hideDialog(context); // GifLoaderDialogUtils.hideDialog(context);
onWrongActivationCode(activation.errorEndUserMessage); onWrongActivationCode(activation.errorEndUserMessage);
return; return;
} else if(activation.messageStatus ==2){
onWrongActivationCode(activation.errorEndUserMessage);
return;
} else if (registerd_data?.isRegister == true) { } else if (registerd_data?.isRegister == true) {
_navigationService.popUntilNamed(AppRoutes.registerNewScreen); _navigationService.popUntilNamed(AppRoutes.registerNewScreen);
// Navigator.popUntil(context, (route) => Utils.route(route, equalsTo: RegisterNew)); // Navigator.popUntil(context, (route) => Utils.route(route, equalsTo: RegisterNew));
@ -372,6 +377,7 @@ class AuthenticationViewModel extends ChangeNotifier {
} else { } else {
if (activation.list != null && activation.list!.isNotEmpty) { if (activation.list != null && activation.list!.isNotEmpty) {
_appState.setAuthenticatedUser(activation.list!.first); _appState.setAuthenticatedUser(activation.list!.first);
} }
_appState.setUserBloodGroup = (activation.patientBlodType ?? ""); _appState.setUserBloodGroup = (activation.patientBlodType ?? "");
_appState.setAppLoginTokenID = activation.authenticationTokenId; _appState.setAppLoginTokenID = activation.authenticationTokenId;
@ -381,7 +387,9 @@ class AuthenticationViewModel extends ChangeNotifier {
if (isUserAgreedBefore) { if (isUserAgreedBefore) {
navigateToHomeScreen(); navigateToHomeScreen();
} else { } else {
getUserAgreementContent(request: request); navigateToHomeScreen();
//Agreement page not designed yet so we are navigating to home screen directly
// getUserAgreementContent(request: request);
} }
// TODO: setPreferences and stuff // TODO: setPreferences and stuff
// sharedPref.remove(FAMILY_FILE); // sharedPref.remove(FAMILY_FILE);
@ -457,7 +465,34 @@ class AuthenticationViewModel extends ChangeNotifier {
} }
Future<void> onWrongActivationCode({String? message}) async { Future<void> onWrongActivationCode({String? message}) async {
// TODO: HANDLE THIS VIA BOTTOM SHEET await _dialogService.showErrorBottomSheet(message: message ?? "Something went wrong. ", onOkPressed: () {});
}
loginWithFingerPrintFace(int selectedOption) async {
_localAuthService.authenticate().then((value) {
if (value) {
// we have to handle this if verification true;
checkActivationCode(otpTypeEnum: OTPTypeEnum.faceIDFingerprint, activationCode: 0000, onWrongActivationCode: (String? message) { });
// authenticated = true;
notifyListeners();
// navigateToHomeScreen();
} else {
//authenticated = false;
notifyListeners();
}
});
this.selectedOption = selectedOption;
notifyListeners();
}
checkLastLoginStatus(Function() onSuccess) async {
if(_appState.getSelectDeviceByImeiRespModelElement !=null && (_appState.getSelectDeviceByImeiRespModelElement!.logInType ==1 || _appState.getSelectDeviceByImeiRespModelElement!.logInType ==4)){
Future.delayed(Duration(seconds: 1),(){
onSuccess();
});
}
} }
@override @override

@ -805,5 +805,9 @@ abstract class LocaleKeys {
static const checkAvailability = 'checkAvailability'; static const checkAvailability = 'checkAvailability';
static const readInstructions = 'readInstructions'; static const readInstructions = 'readInstructions';
static const searchLabReport = 'searchLabReport'; static const searchLabReport = 'searchLabReport';
static const lastloginBy = 'lastloginBy';
static const allSet ='allSet';
static const enableQuickLogin = 'enableQuickLogin';
static const enableMsg = 'enableMsg';
static const notNow = 'notNow';
} }

@ -99,6 +99,7 @@ void main() async {
errorHandlerService: getIt(), errorHandlerService: getIt(),
navigationService: getIt(), navigationService: getIt(),
cacheService: getIt(), cacheService: getIt(),
localAuthService: getIt(),
), ),
), ),
], child: MyApp()), ], child: MyApp()),

@ -0,0 +1,136 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:hmg_patient_app_new/core/app_assets.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/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';
class QuickLogin extends StatefulWidget {
final VoidCallback onPressed;
final bool isDone;
const QuickLogin({super.key, required this.onPressed, this.isDone = false});
@override
_QuickLogin createState() => _QuickLogin();
}
class _QuickLogin extends State<QuickLogin> {
@override
Widget build(BuildContext context) {
return Container(
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(24),
topRight: Radius.circular(24),
),
),
padding: const EdgeInsets.all(24),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
widget.isDone
? Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
InkWell(
onTap: () {
Navigator.pop(context, true);
},
child: Utils.buildSvgWithAssets(icon: AppAssets.cross_circle)),
],
),
Utils.showLottie(context: context, assetPath: AppAnimations.checkmark, width: 120, height: 120, repeat: true),
LocaleKeys.allSet.tr().toText16(textAlign:
TextAlign.center, weight: FontWeight.w500)
// Text(
// ' TranslationBase.of(context).allSet',
// textAlign: TextAlign.center,
// style: context.dynamicTextStyle(
// fontSize: 16,
// fontWeight: FontWeight.w500,
// color: Colors.black,
// ),
// ),
],
)
: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Image.asset(
AppAssets.lockIcon,
height: 101,
),
const SizedBox(height: 10),
LocaleKeys.enableQuickLogin.tr().toText26(isBold: true),
// Text(
// ' TranslationBase.of(context).enableQuickLogin',
// style: context.dynamicTextStyle(
// fontSize: 26,
// fontWeight: FontWeight.bold,
// color: Colors.black,
// ),
// ),
const SizedBox(height: 5),
LocaleKeys.enableQuickLogin.tr().toText16(color: AppColors.quickLoginColor),
// Description
// Text(
// 'TranslationBase.of(context).enableMsg',
// style: context.dynamicTextStyle(
// fontSize: 16,
// color: Color(0xFF666666),
// height: 1.5,
// ),
//),
const SizedBox(height: 24),
// Buttons
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Expanded(
child: CustomButton(
text:LocaleKeys.enableQuickLogin.tr(),
onPressed: () {
widget.onPressed();
},
backgroundColor: Color(0xffED1C2B),
borderColor: Color(0xffED1C2B),
textColor: Colors.white,
icon:AppAssets.apple_finder,
)),
],
),
SizedBox(
height: 16,
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Expanded(
child: CustomButton(
text: LocaleKeys.notNow.tr(),
onPressed: () {
Navigator.pop(context, true);
},
backgroundColor: Color(0xffFEE9EA),
borderColor: Color(0xffFEE9EA),
textColor: Colors.red,
// icon: "assets/images/svg/apple-finder.svg",
)),
],
),
],
)
],
),
);
}
}

@ -2,37 +2,51 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:hmg_patient_app_new/core/app_assets.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/enums.dart'; import 'package:hmg_patient_app_new/core/enums.dart';
import 'package:hmg_patient_app_new/core/utils/date_util.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/core/utils/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/string_extensions.dart';
import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/authentication/login.dart'; import 'package:hmg_patient_app_new/presentation/authentication/login.dart';
import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/appbar/app_bar_widget.dart'; import 'package:hmg_patient_app_new/widgets/appbar/app_bar_widget.dart';
import 'package:hmg_patient_app_new/widgets/bottomsheet/generic_bottom_sheet.dart'; import 'package:hmg_patient_app_new/widgets/bottomsheet/generic_bottom_sheet.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
import 'package:provider/provider.dart';
class SavedLogin extends StatefulWidget { class SavedLogin extends StatefulWidget {
// final SelectDeviceIMEIRES savedLoginData;
// const SavedLogin(this.savedLoginData, {Key? key}) : super(key: key);
const SavedLogin(); const SavedLogin({Key? key}) : super(key: key);
@override @override
_SavedLogin createState() => _SavedLogin(); _SavedLogin createState() => _SavedLogin();
} }
class _SavedLogin extends State<SavedLogin> { class _SavedLogin extends State<SavedLogin> {
LoginTypeEnum loginType = LoginTypeEnum.sms;
LoginTypeEnum loginType = LoginTypeEnum.sms;
late AuthenticationViewModel authVm;
late AppState appState;
@override @override
void initState() { void initState() {
authVm = context.read<AuthenticationViewModel>();
appState = getIt.get<AppState>();
authVm.phoneNumberController.text = appState.getSelectDeviceByImeiRespModelElement!.mobile!;
authVm.nationalIdController.text = appState.getSelectDeviceByImeiRespModelElement!.identificationNo!;
super.initState(); super.initState();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: CustomAppBar( appBar: CustomAppBar(
onBackPressed: () {}, onBackPressed: () {},
@ -48,7 +62,7 @@ class _SavedLogin extends State<SavedLogin> {
// Welcome back text // Welcome back text
LocaleKeys.welcomeBack.tr().toText16(color: AppColors.inputLabelTextColor), LocaleKeys.welcomeBack.tr().toText16(color: AppColors.inputLabelTextColor),
SizedBox(height: 16.h), SizedBox(height: 16.h),
("widget.savedLoginData.name!.toLowerCase().capitalizeFirstofEach").toText26(isBold: true, height: 26 / 36, color: AppColors.textColor), appState.getSelectDeviceByImeiRespModelElement!.name!.toCamelCase.toText26(isBold: true, height: 26 / 36, color: AppColors.textColor),
SizedBox(height: 24.h), SizedBox(height: 24.h),
Container( Container(
padding: EdgeInsets.all(16.h), padding: EdgeInsets.all(16.h),
@ -63,22 +77,25 @@ class _SavedLogin extends State<SavedLogin> {
child: Column( child: Column(
children: [ children: [
// Last login info // Last login info
('LocaleKeys.lastloginBy.tr()' + ' {getType(widget.savedLoginData.logInType!, context)}').toText14(isBold: true, color: AppColors.greyTextColor),
('widget.savedLoginData.createdOn != null ? DateUtil.getFormattedDate(DateUtil.convertStringToDate(widget.savedLoginData.createdOn!), "d MMMM, y at HH:mm") : --') ("${LocaleKeys.lastloginBy.tr() } ${LoginTypeExtension.fromValue(appState.getSelectDeviceByImeiRespModelElement!.logInType!)!.displayName}"
).toText14(isBold: true, color: AppColors.greyTextColor),
(appState.getSelectDeviceByImeiRespModelElement!.createdOn != null ? DateUtil.getFormattedDate(DateUtil.convertStringToDate(appState.getSelectDeviceByImeiRespModelElement!.createdOn!), "d MMMM, y at HH:mm") : '--')
.toText16(isBold: true, color: AppColors.textColor), .toText16(isBold: true, color: AppColors.textColor),
Container(margin: EdgeInsets.all(16.h), child: Utils.buildSvgWithAssets(icon: getTypeIcons(loginType.toInt), iconColor: loginType.toInt == 4 ? null : AppColors.primaryRedColor)), Container(margin: EdgeInsets.all(16.h), child: Utils.buildSvgWithAssets(icon: getTypeIcons(loginType.toInt), height: 54, width: 54, iconColor: loginType.toInt == 4 ? null : AppColors.primaryRedColor)),
// Face ID login button // Face ID login button
Container( SizedBox(
height: 45, height: 45,
child: CustomButton( child: CustomButton(
text: "${LocaleKeys.loginBy.tr()} ${loginType.displayName}", text: "${LocaleKeys.loginBy.tr()} ${loginType.displayName}",
onPressed: () { onPressed: () {
if (loginType == LoginTypeEnum.fingerprint || loginType == LoginTypeEnum.face) { if (loginType == LoginTypeEnum.fingerprint || loginType == LoginTypeEnum.face) {
// loginWithFingerPrintFace(loginType.toInt, widget.savedLoginData.iMEI!); authVm.loginWithFingerPrintFace(loginType.toInt);
} else { }
int? val = loginType.toInt; else {
//checkUserAuthentication(val); // int? val = loginType.toInt;
authVm.checkUserAuthentication(otpTypeEnum: loginType == LoginTypeEnum.sms ? OTPTypeEnum.sms : OTPTypeEnum.whatsapp);
} }
}, },
backgroundColor: Color(0xffED1C2B), backgroundColor: Color(0xffED1C2B),
@ -104,7 +121,7 @@ class _SavedLogin extends State<SavedLogin> {
), ),
const SizedBox(height: 24), const SizedBox(height: 24),
// OTP login button // OTP login button
loginType != null && loginType.toInt != 1 loginType.toInt != 1
? Column( ? Column(
children: [ children: [
loginType.toInt != 1 loginType.toInt != 1
@ -140,7 +157,7 @@ class _SavedLogin extends State<SavedLogin> {
Navigator.of(context).pop(); Navigator.of(context).pop();
loginType = LoginTypeEnum.sms; loginType = LoginTypeEnum.sms;
int? val = loginType.toInt; int? val = loginType.toInt;
// checkUserAuthentication(val); authVm.checkUserAuthentication(otpTypeEnum:OTPTypeEnum.sms );
}, },
backgroundColor: AppColors.primaryRedColor, backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedBorderColor, borderColor: AppColors.primaryRedBorderColor,
@ -163,7 +180,7 @@ class _SavedLogin extends State<SavedLogin> {
Navigator.of(context).pop(); Navigator.of(context).pop();
loginType = LoginTypeEnum.whatsapp; loginType = LoginTypeEnum.whatsapp;
int? val = loginType.toInt; int? val = loginType.toInt;
// checkUserAuthentication(val); authVm.checkUserAuthentication(otpTypeEnum:OTPTypeEnum.whatsapp );
}, },
backgroundColor: AppColors.transparent, backgroundColor: AppColors.transparent,
borderColor: AppColors.textColor, borderColor: AppColors.textColor,
@ -195,11 +212,12 @@ class _SavedLogin extends State<SavedLogin> {
text: "${LocaleKeys.loginBy.tr()} ${LoginTypeEnum.whatsapp.displayName}", text: "${LocaleKeys.loginBy.tr()} ${LoginTypeEnum.whatsapp.displayName}",
onPressed: () { onPressed: () {
if (loginType == LoginTypeEnum.fingerprint || loginType == LoginTypeEnum.face) { if (loginType == LoginTypeEnum.fingerprint || loginType == LoginTypeEnum.face) {
// loginWithFingerPrintFace(loginType.toInt, "iMEI"); authVm.loginWithFingerPrintFace(loginType.toInt);
} else { } else {
loginType = LoginTypeEnum.whatsapp; loginType = LoginTypeEnum.whatsapp;
int? val = loginType.toInt; int? val = loginType.toInt;
// checkUserAuthentication(val); authVm.checkUserAuthentication(otpTypeEnum:OTPTypeEnum.whatsapp );
} }
}, },
backgroundColor: AppColors.whiteColor, backgroundColor: AppColors.whiteColor,

@ -11,14 +11,17 @@ 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/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart'; import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/authentication/quick_login.dart';
import 'package:hmg_patient_app_new/presentation/home/data/landing_page_data.dart'; import 'package:hmg_patient_app_new/presentation/home/data/landing_page_data.dart';
import 'package:hmg_patient_app_new/presentation/home/widgets/habib_wallet_card.dart'; import 'package:hmg_patient_app_new/presentation/home/widgets/habib_wallet_card.dart';
import 'package:hmg_patient_app_new/presentation/home/widgets/large_service_card.dart'; import 'package:hmg_patient_app_new/presentation/home/widgets/large_service_card.dart';
import 'package:hmg_patient_app_new/presentation/home/widgets/small_service_card.dart'; import 'package:hmg_patient_app_new/presentation/home/widgets/small_service_card.dart';
import 'package:hmg_patient_app_new/presentation/home/widgets/welcome_widget.dart';
import 'package:hmg_patient_app_new/presentation/medical_file/medical_file_page.dart'; import 'package:hmg_patient_app_new/presentation/medical_file/medical_file_page.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart'; import 'package:hmg_patient_app_new/services/navigation_service.dart';
import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.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/custom_tab_bar.dart' show CustomTabBar; import 'package:hmg_patient_app_new/widgets/custom_tab_bar.dart' show CustomTabBar;
import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart'; import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -31,11 +34,25 @@ class LandingPage extends StatefulWidget {
} }
class _LandingPageState extends State<LandingPage> { class _LandingPageState extends State<LandingPage> {
late final AuthenticationViewModel authVM;
@override
void initState() {
authVM = context.read<AuthenticationViewModel>();
if(mounted) {
authVM.checkLastLoginStatus(() {
showQuickLogin(context, false);
});
}
super.initState();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
AppState appState = getIt.get<AppState>(); AppState appState = getIt.get<AppState>();
NavigationService navigationService = getIt.get<NavigationService>(); NavigationService navigationService = getIt.get<NavigationService>();
final AuthenticationViewModel authenticationViewModel = context.read<AuthenticationViewModel>();
return Scaffold( return Scaffold(
backgroundColor: AppColors.bgScaffoldColor, backgroundColor: AppColors.bgScaffoldColor,
body: SingleChildScrollView( body: SingleChildScrollView(
@ -46,32 +63,54 @@ class _LandingPageState extends State<LandingPage> {
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
CustomButton( appState.isAuthenticated
text: LocaleKeys.loginOrRegister.tr(context: context), ? WelcomeWidget(
onPressed: () async { onTap: () {},
await authenticationViewModel.onLoginPressed(); name: ('${appState.getAuthenticatedUser()!.firstName!} ${appState.getAuthenticatedUser()!.lastName!}'),
}, imageUrl: appState.getAuthenticatedUser()?.gender == 1 ? AppAssets.male_img : AppAssets.femaleImg,
backgroundColor: Color(0xffFEE9EA), )
borderColor: Color(0xffFEE9EA), : CustomButton(
textColor: Color(0xffED1C2B), text: LocaleKeys.loginOrRegister.tr(context: context),
fontSize: 16, onPressed: () async {
fontWeight: FontWeight.w500, await authVM.onLoginPressed();
borderRadius: 12, },
padding: EdgeInsets.fromLTRB(10, 0, 10, 0), backgroundColor: Color(0xffFEE9EA),
height: 50, borderColor: Color(0xffFEE9EA),
), textColor: Color(0xffED1C2B),
Utils.buildSvgWithAssets( fontSize: 16,
icon: AppAssets.contact_icon, fontWeight: FontWeight.w500,
width: 24, borderRadius: 12,
height: 24, padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
).onPress(() { height: 50,
Navigator.of(context).push( ),
FadePage( Row(
page: MedicalFilePage(), children: [
// page: LoginScreen(), Utils.buildSvgWithAssets(icon: AppAssets.bell, height: 20, width: 20).onPress(() {
), Navigator.of(context).push(
); FadePage(
}), page: MedicalFilePage(),
// page: LoginScreen(),
),
);
}).paddingSymmetrical(8.h, 0),
Utils.buildSvgWithAssets(icon: AppAssets.search_icon, height: 20, width: 20).onPress(() {
Navigator.of(context).push(
FadePage(
page: MedicalFilePage(),
// page: LoginScreen(),
),
);
}).paddingSymmetrical(8.h, 0),
Utils.buildSvgWithAssets(icon: AppAssets.contact_icon, height: 20, width: 20).onPress(() {
Navigator.of(context).push(
FadePage(
page: MedicalFilePage(),
// page: LoginScreen(),
),
);
}).paddingSymmetrical(8.h, 0),
],
)
], ],
).paddingSymmetrical(24.h, 0.h), ).paddingSymmetrical(24.h, 0.h),
), ),
@ -275,4 +314,21 @@ class _LandingPageState extends State<LandingPage> {
), ),
); );
} }
void showQuickLogin(BuildContext context, bool isDone) {
showCommonBottomSheet(
context,
title: "",
child: QuickLogin(
isDone: isDone,
onPressed: () {
// sharedPref.setBool(HAS_ENABLED_QUICK_LOGIN, true);
// loginWithFingerPrintFace(3, 1, user, deviceToken);
},
),
height: 400,
isFullScreen: false,
callBackFunc: (str) {},
);
}
} }

@ -0,0 +1,56 @@
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_assets.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/theme/colors.dart';
class WelcomeWidget extends StatelessWidget {
final String name;
final String imageUrl;
final VoidCallback? onTap;
const WelcomeWidget({
super.key,
required this.name,
required this.imageUrl,
this.onTap,
});
@override
Widget build(BuildContext context) {
return InkWell(
onTap: onTap,
borderRadius: BorderRadius.circular(30),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
// Profile image
Image.asset(imageUrl, width: 40, height: 40),
const SizedBox(width: 10),
// Text column
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Welcome".toText14(color: AppColors.greyTextColor),
Row(
children: [
name.toText16(isBold: true),
const SizedBox(width: 4),
const Icon(Icons.keyboard_arrow_down, size: 20, color: Colors.black),
],
),
],
),
],
),
);
}
}

@ -64,7 +64,7 @@ class _InsuranceHomePageState extends State<InsuranceHomePage> {
insuranceVM.setIsInsuranceHistoryLoading(true); insuranceVM.setIsInsuranceHistoryLoading(true);
insuranceVM.getPatientInsuranceCardHistory(); insuranceVM.getPatientInsuranceCardHistory();
showCommonBottomSheet(context, showCommonBottomSheet(context,
child: InsuranceHistory(), callBackFunc: () {}, title: "", height: ResponsiveExtension.screenHeight * 0.65, isCloseButtonVisible: false, isFullScreen: false); child: InsuranceHistory(), callBackFunc: (str){}, title: "", height: ResponsiveExtension.screenHeight * 0.65, isCloseButtonVisible: false, isFullScreen: false);
}, },
backgroundColor: AppColors.primaryRedColor.withOpacity(0.1), backgroundColor: AppColors.primaryRedColor.withOpacity(0.1),
borderColor: AppColors.primaryRedColor.withOpacity(0.0), borderColor: AppColors.primaryRedColor.withOpacity(0.0),

@ -120,7 +120,7 @@ class PatientInsuranceCard extends StatelessWidget {
insuranceViewModel.setIsInsuranceUpdateDetailsLoading(true); insuranceViewModel.setIsInsuranceUpdateDetailsLoading(true);
insuranceViewModel.getPatientInsuranceDetailsForUpdate(); insuranceViewModel.getPatientInsuranceDetailsForUpdate();
showCommonBottomSheet(context, showCommonBottomSheet(context,
child: PatientInsuranceCardUpdateCard(), callBackFunc: () {}, title: "", height: ResponsiveExtension.screenHeight * 0.42, isCloseButtonVisible: false, isFullScreen: false); child: PatientInsuranceCardUpdateCard(), callBackFunc: (str) {}, title: "", height: ResponsiveExtension.screenHeight * 0.42, isCloseButtonVisible: false, isFullScreen: false);
}, },
backgroundColor: AppColors.bgGreenColor.withOpacity(0.20), backgroundColor: AppColors.bgGreenColor.withOpacity(0.20),
borderColor: AppColors.bgGreenColor.withOpacity(0.0), borderColor: AppColors.bgGreenColor.withOpacity(0.0),

@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/extensions/route_extensions.dart'; import 'package:hmg_patient_app_new/extensions/route_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart'; import 'package:hmg_patient_app_new/services/navigation_service.dart';
abstract class DialogService { abstract class DialogService {
@ -70,7 +71,9 @@ class _ErrorBottomSheet extends StatelessWidget {
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
), ),
), ),
child: const Text("OK"), child: const Text("OK", style: TextStyle(color: Colors.white)).onPress((){
Navigator.of(context).pop();
}),
), ),
], ],
), ),

@ -0,0 +1,40 @@
import 'package:local_auth/local_auth.dart';
import 'logger_service.dart';
class LocalAuthService {
final LocalAuthentication localAuth;
final LoggerService loggerService;
LocalAuthService({required this.localAuth, required this.loggerService});
Future<bool> authenticate() async {
try {
bool isAuthenticated = await localAuth.authenticate(
localizedReason: 'Please authenticate to proceed',
options: const AuthenticationOptions(
biometricOnly: true,
stickyAuth: true,
),
);
return isAuthenticated;
} catch (e) {
return false;
}
}
Future<bool> canCheckBiometrics() async {
try {
return await localAuth.canCheckBiometrics;
} catch (e) {
return false;
}
}
Future<List<BiometricType>> getAvailableBiometrics() async {
try {
return await localAuth.getAvailableBiometrics();
} catch (e) {
return [];
}
}
}

@ -58,4 +58,6 @@ static const Color warningLightColor = Color(0xFFFFCC00);
static const Color greyLightColor = Color(0xFFEFEFF0); static const Color greyLightColor = Color(0xFFEFEFF0);
static const Color bottomNAVBorder = Color(0xFFEEEEEE); static const Color bottomNAVBorder = Color(0xFFEEEEEE);
static const Color quickLoginColor = Color(0xFF666666);
} }

Loading…
Cancel
Save