// ignore_for_file: use_build_context_synchronously import 'package:bookmywages/consts_widgets/app_assets.dart'; import 'package:bookmywages/consts_widgets/app_colors.dart'; import 'package:bookmywages/consts_widgets/comman_button.dart'; import 'package:bookmywages/consts_widgets/comman_textformfiled.dart'; import 'package:bookmywages/model/login_model.dart'; import 'package:bookmywages/routers/consts_router.dart'; import 'package:bookmywages/viewmodel/api_controller.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:get/get.dart'; import 'package:shared_preferences/shared_preferences.dart'; class LoginScreen extends ConsumerStatefulWidget { const LoginScreen({super.key}); @override ConsumerState createState() => _LoginScreenState(); } class _LoginScreenState extends ConsumerState { final TextEditingController _usernameController = TextEditingController(); final TextEditingController _passwordController = TextEditingController(); bool _obscurePassword = true; // Add form key and error messages final _formKey = GlobalKey(); String? _emailError; String? _passwordError; @override void dispose() { _usernameController.dispose(); _passwordController.dispose(); super.dispose(); } // Validation methods void _validateEmail(String value) { if (value.isEmpty) { setState(() => _emailError = 'Email is required'); } else if (!RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(value)) { setState(() => _emailError = 'Enter a valid email'); } else { setState(() => _emailError = null); } } void _validatePassword(String value) { if (value.isEmpty) { setState(() => _passwordError = 'Password is required'); } else if (value.length < 4) { setState(() => _passwordError = 'Password must be at least 4 characters'); } else { setState(() => _passwordError = null); } } @override Widget build(BuildContext context) { final screenSize = MediaQuery.of(context).size; final double horizontalPadding = screenSize.width * 0.05; final double imageHeight = screenSize.height * 0.45; return Scaffold( backgroundColor: AppColors.secondprimary, resizeToAvoidBottomInset: true, body: SingleChildScrollView( child: Column( children: [ // Image Image.asset( AppAssets.login, width: screenSize.width, height: imageHeight, fit: BoxFit.cover, ), // Overlapping Login Container using Transform Transform.translate( offset: const Offset(0, -100), child: Padding( padding: EdgeInsets.symmetric(horizontal: horizontalPadding), child: Container( width: double.infinity, decoration: BoxDecoration( borderRadius: BorderRadius.circular(32.73), border: Border.all( width: 1.09, color: const Color(0xFFA39898), ), boxShadow: const [ BoxShadow( offset: Offset(0, -4), blurRadius: 12.3, color: Color(0x66E0E0E0), ), BoxShadow( offset: Offset(0, 4), blurRadius: 4, color: Color(0x66000000), ), ], color: Colors.white, ), child: Padding( padding: EdgeInsets.all(screenSize.width * 0.05), child: Form( key: _formKey, child: Column( children: [ const SizedBox(height: 20), const Text( "Sign in", style: TextStyle( fontSize: 32, fontFamily: "Gilroy-ExtraBold", fontWeight: FontWeight.w800, height: 1.0, letterSpacing: 0.64, ), ), SizedBox(height: screenSize.height * 0.03), CommonTextFormField( hintText: 'Enter your email', controller: _usernameController, prefixIcon: const Icon( Icons.person, color: AppColors.hittext, ), errorText: _emailError, onChanged: (value) { _validateEmail(value); }, ), const SizedBox(height: 42), CommonTextFormField( hintText: 'Enter your password', controller: _passwordController, obscureText: _obscurePassword, prefixIcon: const Icon( Icons.lock, color: AppColors.hittext, ), errorText: _passwordError, onChanged: (value) { _validatePassword(value); }, suffixIcon: IconButton( icon: Icon( _obscurePassword ? Icons.visibility_off : Icons.visibility, color: AppColors.hittext, ), onPressed: () { setState(() { _obscurePassword = !_obscurePassword; }); }, ), ), Align( alignment: Alignment.centerRight, child: TextButton( onPressed: () {}, child: const Text( "Forgot Password?", style: TextStyle( fontFamily: 'Gilroy-Medium', fontWeight: FontWeight.w400, fontSize: 14, height: 1.0, letterSpacing: 0.1357, color: Color(0xFFFF0000), ), ), ), ), const SizedBox(height: 20), CommanButton( text: 'Sign in', textStyle: const TextStyle( fontFamily: 'Gilroy-Black', fontWeight: FontWeight.w800, fontSize: 20, height: 1.0, color: AppColors.secondprimary, ), onPressed: () { // Validate all fields _validateEmail(_usernameController.text); _validatePassword(_passwordController.text); if (_emailError == null && _passwordError == null) { final loginModel = LoginModel( email: _usernameController.text.trim(), password: _passwordController.text.trim(), ); ref .read( loginFutureProvider(loginModel).future, ) .then((response) async { Fluttertoast.showToast( msg: 'Login Successful: ${response['message']}', toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.BOTTOM, backgroundColor: Colors.green, textColor: Colors.white, fontSize: 10.0, ); final userId = response['data'][0]['id']; final prefs = await SharedPreferences.getInstance(); final isVerified = prefs.getString( 'is_verified', ); if (isVerified == '1') { Get.toNamed(RouterConts.homescreen); } else { Get.toNamed( RouterConts.otp, arguments: userId, ); // Replace with your OTP route } }) .catchError((error) { Fluttertoast.showToast( msg: 'Login Failed: $error', toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.BOTTOM, backgroundColor: Colors.red, textColor: Colors.white, fontSize: 10.0, ); }); } else { Fluttertoast.showToast( msg: 'Please fix all errors', toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.BOTTOM, backgroundColor: Colors.orange, textColor: Colors.white, fontSize: 10.0, ); } }, isPrimary: true, backgroundColor: AppColors.primary, textColor: AppColors.secondprimary, width: 230, ), SizedBox(height: 30), RichText( text: TextSpan( text: "Didn't have account? ", style: TextStyle( fontFamily: 'Gilroy-ExtraBold', fontWeight: FontWeight.w700, fontSize: 17, height: 1.0, letterSpacing: 0.01, color: Color(0xFF9F9F9F), ), children: [ TextSpan( text: "Sign up", style: TextStyle(color: Color(0xFF0066FF)), recognizer: TapGestureRecognizer() ..onTap = () { Get.toNamed(RouterConts.siguppage); }, ), ], ), ), SizedBox(height: 30), ], ), ), ), ), ), ), ], ), ), ); } }