last 16-10-2025
This commit is contained in:
commit
7546b7348c
269 files changed
+36404
No files matched your search
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,301 @@
|
||||
// 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),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,300 @@
|
||||
|
||||
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/model/otp_model.dart' show OtpModel;
|
||||
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:pinput/pinput.dart';
|
||||
|
||||
class OtpScreen extends ConsumerStatefulWidget {
|
||||
final String? userId;
|
||||
|
||||
const OtpScreen({super.key, required this.userId});
|
||||
|
||||
@override
|
||||
ConsumerState<OtpScreen> createState() => _OtpScreenState();
|
||||
}
|
||||
|
||||
class _OtpScreenState extends ConsumerState<OtpScreen> {
|
||||
String _enteredOtp = '';
|
||||
bool _isLoading = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
// No need to parse userId, keeping it as String
|
||||
}
|
||||
|
||||
void _verifyOtp() async {
|
||||
if (widget.userId!.isEmpty || _enteredOtp.length != 4) {
|
||||
Fluttertoast.showToast(
|
||||
msg: "Invalid OTP or missing user information",
|
||||
toastLength: Toast.LENGTH_SHORT,
|
||||
gravity: ToastGravity.BOTTOM,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
setState(() {
|
||||
_isLoading = true;
|
||||
});
|
||||
|
||||
try {
|
||||
// Use userId directly as String
|
||||
final otpModel = OtpModel(
|
||||
userId: widget.userId.toString(),
|
||||
otp: _enteredOtp,
|
||||
);
|
||||
|
||||
final result = await ref.read(otpVerificationProvider(otpModel).future);
|
||||
|
||||
if (mounted) {
|
||||
Fluttertoast.showToast(
|
||||
msg: "Verification Successful: ${result['message'] ?? 'Success'}",
|
||||
toastLength: Toast.LENGTH_SHORT,
|
||||
gravity: ToastGravity.BOTTOM,
|
||||
backgroundColor: Colors.green,
|
||||
textColor: Colors.white,
|
||||
);
|
||||
// context.push(RouterConts.homescreen);
|
||||
}
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
Fluttertoast.showToast(
|
||||
msg: "Verification Failed: ${e.toString()}",
|
||||
toastLength: Toast.LENGTH_LONG,
|
||||
gravity: ToastGravity.BOTTOM,
|
||||
backgroundColor: Colors.red,
|
||||
textColor: Colors.white,
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _resendOtp() async {
|
||||
if (widget.userId!.isEmpty) {
|
||||
Fluttertoast.showToast(
|
||||
msg: "Missing user information",
|
||||
toastLength: Toast.LENGTH_SHORT,
|
||||
gravity: ToastGravity.BOTTOM,
|
||||
backgroundColor: Colors.red,
|
||||
textColor: Colors.white,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
setState(() {
|
||||
_isLoading = true;
|
||||
});
|
||||
|
||||
try {
|
||||
// Implement resend OTP API call using String userId
|
||||
// For example:
|
||||
// final result = await ref.read(resendOtpProvider(widget.userId).future);
|
||||
|
||||
if (mounted) {
|
||||
Fluttertoast.showToast(
|
||||
msg: "OTP resent successfully",
|
||||
toastLength: Toast.LENGTH_SHORT,
|
||||
gravity: ToastGravity.BOTTOM,
|
||||
backgroundColor: Colors.green,
|
||||
textColor: Colors.white,
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
Fluttertoast.showToast(
|
||||
msg: "Failed to resend OTP: ${e.toString()}",
|
||||
toastLength: Toast.LENGTH_LONG,
|
||||
gravity: ToastGravity.BOTTOM,
|
||||
backgroundColor: Colors.red,
|
||||
textColor: Colors.white,
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final screenSize = MediaQuery.of(context).size;
|
||||
final double horizontalPadding = screenSize.width * 0.05;
|
||||
|
||||
return WillPopScope(
|
||||
onWillPop: () async {
|
||||
// context.push(RouterConts.siguppage);
|
||||
return false;
|
||||
},
|
||||
child: Scaffold(
|
||||
backgroundColor: AppColors.secondprimary,
|
||||
resizeToAvoidBottomInset: true,
|
||||
body: SafeArea(
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
Image.asset(
|
||||
AppAssets.login,
|
||||
width: screenSize.width,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
Transform.translate(
|
||||
offset: const Offset(0, -150),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
margin: EdgeInsets.symmetric(horizontal: horizontalPadding),
|
||||
padding: EdgeInsets.all(screenSize.width * 0.05),
|
||||
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: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const SizedBox(height: 20),
|
||||
const Text(
|
||||
"OTP Verification",
|
||||
style: TextStyle(
|
||||
fontSize: 28,
|
||||
fontFamily: "Gilroy-ExtraBold",
|
||||
fontWeight: FontWeight.w800,
|
||||
height: 1.0,
|
||||
letterSpacing: 0.64,
|
||||
),
|
||||
),
|
||||
SizedBox(height: screenSize.height * 0.03),
|
||||
const Text(
|
||||
"Enter the OTP sent to your number",
|
||||
style: TextStyle(
|
||||
fontFamily: 'Gilroy-Medium',
|
||||
fontWeight: FontWeight.w400,
|
||||
fontSize: 16,
|
||||
height: 1.0,
|
||||
letterSpacing: 0.16,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 27),
|
||||
Pinput(
|
||||
length: 4,
|
||||
defaultPinTheme: PinTheme(
|
||||
width: 56,
|
||||
height: 56,
|
||||
textStyle: const TextStyle(
|
||||
fontSize: 20,
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
decoration: const BoxDecoration(
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: Colors.grey,
|
||||
width: 3,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
focusedPinTheme: PinTheme(
|
||||
width: 56,
|
||||
height: 56,
|
||||
textStyle: const TextStyle(
|
||||
fontSize: 20,
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
decoration: const BoxDecoration(
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: AppColors.primary,
|
||||
width: 3,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
onChanged: (pin) => setState(() => _enteredOtp = pin),
|
||||
onCompleted:
|
||||
(pin) => setState(() => _enteredOtp = pin),
|
||||
),
|
||||
const SizedBox(height: 40),
|
||||
RichText(
|
||||
text: TextSpan(
|
||||
text: "Didn't receive code? ",
|
||||
style: const TextStyle(
|
||||
fontFamily: 'Gilroy-ExtraBold',
|
||||
fontWeight: FontWeight.w700,
|
||||
fontSize: 17,
|
||||
height: 1.0,
|
||||
letterSpacing: 0.01,
|
||||
color: Color(0xFF9F9F9F),
|
||||
),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: "Resend",
|
||||
style: const TextStyle(
|
||||
color: Color(0xFF0066FF),
|
||||
),
|
||||
recognizer:
|
||||
TapGestureRecognizer()..onTap = _resendOtp,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 40),
|
||||
CommanButton(
|
||||
text: 'Verify',
|
||||
textStyle: const TextStyle(
|
||||
fontFamily: 'Gilroy-Black',
|
||||
fontWeight: FontWeight.w800,
|
||||
fontSize: 20,
|
||||
height: 1.0,
|
||||
color: AppColors.secondprimary,
|
||||
),
|
||||
onPressed: _verifyOtp,
|
||||
isPrimary: true,
|
||||
backgroundColor: AppColors.primary,
|
||||
textColor: AppColors.secondprimary,
|
||||
width: 230,
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
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/routers/consts_router.dart';
|
||||
import 'package:bookmywages/viewmodel/api_controller.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class SignUpScreen extends ConsumerStatefulWidget {
|
||||
const SignUpScreen({super.key});
|
||||
|
||||
@override
|
||||
ConsumerState<SignUpScreen> createState() => _SignUpScreenState();
|
||||
}
|
||||
|
||||
class _SignUpScreenState extends ConsumerState<SignUpScreen> {
|
||||
final TextEditingController _usernameController = TextEditingController();
|
||||
final TextEditingController _mobilenumberController = TextEditingController();
|
||||
final TextEditingController _emailController = TextEditingController();
|
||||
final TextEditingController _passwordController = TextEditingController();
|
||||
bool _obscurePassword = true;
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_usernameController.dispose();
|
||||
_mobilenumberController.dispose();
|
||||
_emailController.dispose();
|
||||
_passwordController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _onSignUp() async {
|
||||
final userData = {
|
||||
'name': _usernameController.text.trim(),
|
||||
'number': _mobilenumberController.text.trim(),
|
||||
'email': _emailController.text.trim(),
|
||||
'password': _passwordController.text.trim(),
|
||||
};
|
||||
|
||||
try {
|
||||
final result = await ref.read(signupFutureProvider(userData).future);
|
||||
|
||||
final userId = result['data'][0]['id'];
|
||||
|
||||
if (mounted) {
|
||||
Fluttertoast.showToast(
|
||||
msg: "Signup Successful: ${result['message'] ?? 'Success'}",
|
||||
toastLength: Toast.LENGTH_SHORT,
|
||||
gravity: ToastGravity.BOTTOM,
|
||||
backgroundColor: Colors.green,
|
||||
textColor: Colors.white,
|
||||
);
|
||||
|
||||
Get.toNamed(RouterConts.otp, arguments: userId);
|
||||
|
||||
// Pass userId to OTP screen
|
||||
}
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
Fluttertoast.showToast(
|
||||
msg: "Signup Failed: ${e.toString()}",
|
||||
toastLength: Toast.LENGTH_LONG,
|
||||
gravity: ToastGravity.BOTTOM,
|
||||
backgroundColor: Colors.red,
|
||||
textColor: Colors.white,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final screenSize = MediaQuery.of(context).size;
|
||||
final double horizontalPadding = screenSize.width * 0.05;
|
||||
|
||||
// ignore: deprecated_member_use
|
||||
return WillPopScope(
|
||||
onWillPop: () async {
|
||||
// context.push(RouterConts.welcomepage); // Actually go back
|
||||
return false; // Prevent default behavior (optional)
|
||||
},
|
||||
|
||||
child: Scaffold(
|
||||
backgroundColor: AppColors.secondprimary,
|
||||
resizeToAvoidBottomInset: true,
|
||||
body: SafeArea(
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
Image.asset(
|
||||
AppAssets.login,
|
||||
width: screenSize.width,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
Transform.translate(
|
||||
offset: const Offset(0, -150),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
margin: EdgeInsets.symmetric(horizontal: horizontalPadding),
|
||||
padding: EdgeInsets.all(screenSize.width * 0.05),
|
||||
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: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Text(
|
||||
"Sign up",
|
||||
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 username',
|
||||
controller: _usernameController,
|
||||
prefixIcon: const Icon(
|
||||
Icons.person,
|
||||
color: AppColors.hittext,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
CommonTextFormField(
|
||||
hintText: 'Enter your mobile number',
|
||||
controller: _mobilenumberController,
|
||||
prefixIcon: const Icon(
|
||||
Icons.phone,
|
||||
color: AppColors.hittext,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
CommonTextFormField(
|
||||
hintText: 'Enter your email',
|
||||
controller: _emailController,
|
||||
prefixIcon: const Icon(
|
||||
Icons.email,
|
||||
color: AppColors.hittext,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
CommonTextFormField(
|
||||
hintText: 'Enter your password',
|
||||
controller: _passwordController,
|
||||
obscureText: _obscurePassword,
|
||||
prefixIcon: const Icon(
|
||||
Icons.lock,
|
||||
color: AppColors.hittext,
|
||||
),
|
||||
suffixIcon: IconButton(
|
||||
icon: Icon(
|
||||
_obscurePassword
|
||||
? Icons.visibility_off
|
||||
: Icons.visibility,
|
||||
color: AppColors.hittext,
|
||||
),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_obscurePassword = !_obscurePassword;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 15),
|
||||
|
||||
CommanButton(
|
||||
text: 'Sign up',
|
||||
textStyle: const TextStyle(
|
||||
fontFamily: 'Gilroy-Black',
|
||||
fontWeight: FontWeight.w800,
|
||||
fontSize: 20,
|
||||
height: 1.0,
|
||||
color: AppColors.secondprimary,
|
||||
),
|
||||
onPressed: _onSignUp,
|
||||
isPrimary: true,
|
||||
backgroundColor: AppColors.primary,
|
||||
textColor: AppColors.secondprimary,
|
||||
width: 230,
|
||||
),
|
||||
|
||||
const SizedBox(height: 10),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user