302 lines
13 KiB
Dart
302 lines
13 KiB
Dart
// 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<LoginScreen> createState() => _LoginScreenState();
|
|
}
|
|
|
|
class _LoginScreenState extends ConsumerState<LoginScreen> {
|
|
final TextEditingController _usernameController = TextEditingController();
|
|
final TextEditingController _passwordController = TextEditingController();
|
|
bool _obscurePassword = true;
|
|
|
|
// Add form key and error messages
|
|
final _formKey = GlobalKey<FormState>();
|
|
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),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|