You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
cloudsolutions-atoms/lib/new_views/pages/login_page.dart

253 lines
13 KiB
Dart

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<LoginPage> createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
final User _user = User();
late UserProvider _userProvider;
SettingProvider? _settingProvider;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
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<UserProvider>(context);
if (_settingProvider == null) {
_settingProvider = Provider.of<SettingProvider>(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<void> _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);
}
}
}