import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:test_sa/app_strings/app_asset.dart'; import 'package:test_sa/controllers/notification/firebase_notification_manger.dart'; import 'package:test_sa/controllers/providers/settings/app_settings.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/models/new_models/general_response_model.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/new_views/forget_password_module/forget_passwod_verify_otp.dart'; import 'package:test_sa/new_views/pages/land_page/land_page.dart'; import 'package:url_launcher/url_launcher.dart'; import '../../controllers/providers/api/user_provider.dart'; import '../../controllers/providers/settings/setting_provider.dart'; import '../../controllers/validator/validator.dart'; import '../../models/user.dart'; import '../common_widgets/app_filled_button.dart'; import '../common_widgets/app_text_form_field.dart'; class LoginPage extends StatefulWidget { static const String routeName = "/login_page"; const LoginPage({Key? key}) : super(key: key); @override State createState() => _LoginPageState(); } class _LoginPageState extends State { final User _user = User(); late UserProvider _userProvider; SettingProvider? _settingProvider; final GlobalKey _formKey = GlobalKey(); TextEditingController userNameController = TextEditingController(); bool _passwordVisible = false; bool rememberMe = false; bool privacyPolicyChecked = false; @override void initState() { super.initState(); if (FirebaseNotificationManger.token == null) FirebaseNotificationManger.getToken(); } @override Widget build(BuildContext context) { _userProvider = Provider.of(context); if (_settingProvider == null) { _settingProvider = Provider.of(context); rememberMe = _settingProvider!.rememberMe; if (rememberMe) { _user.userName = _settingProvider!.username; userNameController.text = _user.userName ?? ''; _user.password = _settingProvider!.password; } } return Form( key: _formKey, child: Scaffold( backgroundColor: AppColor.background(context), body: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, children: [ Container( width: double.infinity, height: 293.toScreenHeight, padding: EdgeInsets.only(left: 16.toScreenWidth), decoration: BoxDecoration( image: DecorationImage( image: AssetImage(AppAsset.loginTopBg), fit: BoxFit.cover, // Adjusts the image to cover the entire container ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ SizedBox( height: 100.toScreenHeight, ), "logo_white".toPngAsset(width: 110), 25.height, context.translation.signInToYour.customHeadingText(context).custom(color: Colors.white, fontSize: 27, fontWeight: FontWeight.w500), context.translation.account.customHeadingText(context).custom(color: Colors.white, fontSize: 27, fontWeight: FontWeight.w500), 15.height, ], ), ), SizedBox( height: 47.toScreenHeight, ), Padding( padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: [ AppTextFormField( initialValue: _user.userName ?? "", controller: userNameController, backgroundColor: AppColor.fieldBgColor(context), validator: (value) => Validator.hasValue(value!) ? null : context.translation.requiredField, labelText: context.translation.username, style: TextStyle(fontWeight: FontWeight.w500, fontSize: context.isTablet() ? 16 : 12, color: context.isDark ? Colors.white : const Color(0xff3B3D4A)), floatingLabelStyle: TextStyle(fontWeight: FontWeight.w500, fontSize: context.isTablet() ? 16 : 12, color: context.isDark ? Colors.white : const Color(0xff3B3D4A)), labelStyle: TextStyle(fontWeight: FontWeight.w500, fontSize: context.isTablet() ? 16 : 12, color: context.isDark ? Colors.white : const Color(0xff767676)), textInputType: TextInputType.text, showWithoutDecoration: true, contentPadding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth, vertical: 12.toScreenHeight), onSaved: (value) { _user.userName = value; }, ), 16.height, AppTextFormField( initialValue: _user.password ?? "", showWithoutDecoration: true, labelText: context.translation.password, backgroundColor: AppColor.fieldBgColor(context), style: TextStyle(fontWeight: FontWeight.w500, fontSize: context.isTablet() ? 16 : 12, color: context.isDark ? Colors.white : const Color(0xff3B3D4A)), labelStyle: TextStyle(fontWeight: FontWeight.w500, fontSize: context.isTablet() ? 16 : 12, color: context.isDark ? Colors.white : const Color(0xff767676)), floatingLabelStyle: TextStyle(fontWeight: FontWeight.w500, fontSize: context.isTablet() ? 16 : 12, color: context.isDark ? Colors.white : const Color(0xff3B3D4A)), contentPadding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth, vertical: 12.toScreenHeight), obscureText: !_passwordVisible, suffixIcon: Icon( // Based on passwordVisible state choose the icon _passwordVisible ? Icons.visibility : Icons.visibility_off, color: context.isDark ? AppColor.neutral10 : AppColor.neutral20, ).paddingOnly(end: 12).onPress(() { setState(() { _passwordVisible = !_passwordVisible; }); }), validator: (value) => Validator.isValidPassword(value!) ? null : value.isEmpty ? context.translation.requiredField : context.translation.passwordLengthMessage, onSaved: (value) { _user.password = value; }, ), 16.height, Align( alignment: AlignmentDirectional.centerEnd, child: context.translation.forgotPassword.bodyText(context).custom(color: AppColor.primary10, fontWeight: FontWeight.w500).onPress(() async { if (userNameController.text.isNotEmpty) { GeneralResponseModel response = await _userProvider.sendForgetPasswordOtp(context: context, employeeId: userNameController.text); if (response.isSuccess == true) { Navigator.push( context, MaterialPageRoute( builder: (context) => ForgetPasswordVerifyOtpView( data: {'employeeId': userNameController.text, 'phoneNumber': response.data}, ))); // Navigator.push(context, ForgetPasswordVerifyOtpView.routeName); } else { context.showConfirmDialog(response.message ?? context.translation.failedToCompleteRequest); } } else { Fluttertoast.showToast(msg: context.translation.employeeIdIsRequired); } }), ), Row( children: [ Checkbox( value: rememberMe, activeColor: AppColor.blueStatus(context), materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, onChanged: (value) { setState(() { rememberMe = value!; }); }), "Remember Me".bodyText(context).custom(color: context.isDark ? AppColor.primary50 : AppColor.neutral50).expanded, ], ), Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Checkbox( value: privacyPolicyChecked, activeColor: AppColor.blueStatus(context), materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, onChanged: (value) { if (value == null) return; privacyPolicyChecked = value; setState(() {}); }), RichText( text: TextSpan(text: "I have read and agree to ", style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.primary50 : AppColor.neutral50), children: [ TextSpan( text: "Privacy Policy", style: AppTextStyles.bodyText.copyWith(color: AppColor.blueStatus(context), decoration: TextDecoration.underline), recognizer: TapGestureRecognizer() ..onTap = () async { Uri uri = Uri.parse("https://cloudsolutions.com.sa/en/privacy-policy"); try { launchUrl(uri); } catch (ex) {} }), ]), ).expanded, ], ), 16.height, AppFilledButton(label: context.translation.signIn, buttonColor: AppColor.primary10, maxWidth: true, onPressed: _login), ], ), ), ], ), )), ); } Future _login() async { if (!_formKey.currentState!.validate()) return; if (privacyPolicyChecked == false) { "You must agree privacy policy".showToast; return; } _formKey.currentState!.save(); int status = await _userProvider.login(context: context, user: _user); if (status >= 200 && status < 300 && _userProvider.user!.isAuthenticated! ?? false) { await _settingProvider!.setUser(_userProvider.user!); // (await SharedPreferences.getInstance()).remove(ASettings.localAuth); await _settingProvider!.setRememberMe(_user.userName!, _user.password!, rememberMe); //TODO need to verify this here... if (_userProvider.user?.isEnabledFaceId == true) { await _settingProvider!.setAuth(_userProvider.user!.isEnabledFaceId!); } else { (await SharedPreferences.getInstance()).remove(ASettings.localAuth); } Navigator.pushReplacementNamed(context, LandPage.routeName); } else { Fluttertoast.showToast(msg: _userProvider.user?.message ?? context.translation.failedToCompleteRequest); } } }