loginpage changes
This commit is contained in:
commit
1999e63c0f
3
devtools_options.yaml
Normal file
3
devtools_options.yaml
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
description: This file stores settings for Dart & Flutter DevTools.
|
||||||
|
documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
|
||||||
|
extensions:
|
||||||
@ -597,15 +597,15 @@ class _ApprovalListState extends State<ApprovalList> {
|
|||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
fontFamily: "Archivo",
|
fontFamily: "Archivo",
|
||||||
))),
|
))),
|
||||||
DataCell(Text(
|
DataCell(Text(plan.employeeCode ?? "no data",
|
||||||
plan.userName.isNotEmpty
|
|
||||||
? plan.userName
|
|
||||||
: plan.travellerName,
|
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
fontFamily: "Inter",
|
fontFamily: "Inter",
|
||||||
))),
|
))),
|
||||||
DataCell(Text(plan.employeeCode ?? "no data",
|
DataCell(Text(
|
||||||
|
plan.userName.isNotEmpty
|
||||||
|
? plan.userName
|
||||||
|
: plan.travellerName,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
fontFamily: "Inter",
|
fontFamily: "Inter",
|
||||||
|
|||||||
@ -16,11 +16,31 @@ class LoginWidget extends StatefulWidget {
|
|||||||
_LoginWidgetState createState() => _LoginWidgetState();
|
_LoginWidgetState createState() => _LoginWidgetState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum LoginStep { login, forgotEmail, otpReset }
|
||||||
|
|
||||||
class _LoginWidgetState extends State<LoginWidget> {
|
class _LoginWidgetState extends State<LoginWidget> {
|
||||||
final _formKey = GlobalKey<FormState>();
|
final _formKey = GlobalKey<FormState>();
|
||||||
final TextEditingController _emailController = TextEditingController();
|
final TextEditingController _emailController = TextEditingController();
|
||||||
final TextEditingController _passwordController = TextEditingController();
|
final TextEditingController _passwordController = TextEditingController();
|
||||||
|
final TextEditingController _otpController = TextEditingController();
|
||||||
|
final TextEditingController _newPasswordController = TextEditingController();
|
||||||
|
final TextEditingController _confirmPasswordController =
|
||||||
|
TextEditingController();
|
||||||
bool _obscureText = true;
|
bool _obscureText = true;
|
||||||
|
bool _isForgotPassword = false;
|
||||||
|
bool _showOtpResetFields = false;
|
||||||
|
// 🔹 Login Step Enum and State Variable
|
||||||
|
LoginStep _loginStep = LoginStep.login;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_emailController.dispose();
|
||||||
|
_passwordController.dispose();
|
||||||
|
_otpController.dispose();
|
||||||
|
_newPasswordController.dispose();
|
||||||
|
_confirmPasswordController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> storeUserDetails(String token) async {
|
Future<void> storeUserDetails(String token) async {
|
||||||
try {
|
try {
|
||||||
@ -47,7 +67,7 @@ class _LoginWidgetState extends State<LoginWidget> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _login(BuildContext context) async {
|
Future<void> _login(BuildContext context) async {
|
||||||
if (_formKey.currentState!.validate()) {
|
if (_formKey.currentState!.validate()) {
|
||||||
const String url = '$apiUrl/auth/login';
|
const String url = '$apiUrl/auth/login';
|
||||||
|
|
||||||
@ -95,6 +115,108 @@ class _LoginWidgetState extends State<LoginWidget> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _handleSubmit(BuildContext context) async {
|
||||||
|
print('2');
|
||||||
|
if (!_formKey.currentState!.validate()) return;
|
||||||
|
print('3');
|
||||||
|
if (_isForgotPassword && !_showOtpResetFields) {
|
||||||
|
print('11');
|
||||||
|
// Step 1: Send OTP
|
||||||
|
final url = '$apiUrl/forgotPassword/verifyUser';
|
||||||
|
try {
|
||||||
|
final response = await http.post(
|
||||||
|
Uri.parse(url),
|
||||||
|
headers: {'Content-Type': 'application/json'},
|
||||||
|
body: jsonEncode({'email': _emailController.text.trim()}),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
setState(() => _showOtpResetFields = true);
|
||||||
|
setState(() {
|
||||||
|
_isForgotPassword = false;
|
||||||
|
_showOtpResetFields = true;
|
||||||
|
// _clearAllFields();
|
||||||
|
});
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(content: Text("OTP sent to your email")),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
print(response);
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content:
|
||||||
|
Text("${jsonDecode(response.body)['messages']['error']}")),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
ScaffoldMessenger.of(context)
|
||||||
|
.showSnackBar(SnackBar(content: Text("Error: $e")));
|
||||||
|
}
|
||||||
|
} else if (!_isForgotPassword && _showOtpResetFields) {
|
||||||
|
print('22');
|
||||||
|
// Step 2: Verify OTP & Reset Password
|
||||||
|
final url = '$apiUrl/forgotPassword/changePassword';
|
||||||
|
try {
|
||||||
|
print('21');
|
||||||
|
final response = await http.post(
|
||||||
|
Uri.parse(url),
|
||||||
|
headers: {'Content-Type': 'application/json'},
|
||||||
|
body: jsonEncode({
|
||||||
|
'email': _emailController.text.trim(),
|
||||||
|
'otp': _otpController.text.trim(),
|
||||||
|
'new_password': _newPasswordController.text.trim(),
|
||||||
|
'confirm_password': _confirmPasswordController.text.trim(),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
print('22');
|
||||||
|
setState(() {
|
||||||
|
_isForgotPassword = false;
|
||||||
|
_showOtpResetFields = false;
|
||||||
|
_clearAllFields();
|
||||||
|
});
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(content: Text("Password reset successfully")),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
print('23');
|
||||||
|
print('otp wrong');
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content: Text(
|
||||||
|
"Reset failed: ${jsonDecode(response.body)['message']}")),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
ScaffoldMessenger.of(context)
|
||||||
|
.showSnackBar(SnackBar(content: Text("Error: $e")));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Login flow
|
||||||
|
_login(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _clearAllFields() {
|
||||||
|
_emailController.clear();
|
||||||
|
_passwordController.clear();
|
||||||
|
_otpController.clear();
|
||||||
|
_newPasswordController.clear();
|
||||||
|
_confirmPasswordController.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onSubmit(BuildContext context) async {
|
||||||
|
if (_formKey.currentState!.validate()) {
|
||||||
|
if (!_isForgotPassword && !_showOtpResetFields) {
|
||||||
|
await _login(context);
|
||||||
|
} else {
|
||||||
|
print('1');
|
||||||
|
_handleSubmit(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
||||||
/// Layout
|
/// Layout
|
||||||
@ -188,130 +310,376 @@ class _LoginWidgetState extends State<LoginWidget> {
|
|||||||
const SizedBox(height: 18),
|
const SizedBox(height: 18),
|
||||||
|
|
||||||
/// **Email Field**
|
/// **Email Field**
|
||||||
_buildLabel("Email Address"),
|
if (!_isForgotPassword && !_showOtpResetFields) ...[
|
||||||
TextFormField(
|
_buildLabel("Email Address"),
|
||||||
controller: _emailController,
|
TextFormField(
|
||||||
style: TextStyle(
|
controller: _emailController,
|
||||||
fontFamily: "Archivo",
|
style: TextStyle(
|
||||||
fontWeight: FontWeight.w600,
|
fontFamily: "Archivo",
|
||||||
fontSize: 11),
|
fontWeight: FontWeight.w600,
|
||||||
decoration: _inputDecoration("Enter your email address").copyWith(
|
fontSize: 11),
|
||||||
prefixIcon: Icon(
|
decoration:
|
||||||
Icons.email_outlined,
|
_inputDecoration("Enter your email address").copyWith(
|
||||||
size: 16,
|
prefixIcon: Icon(
|
||||||
),
|
Icons.email_outlined,
|
||||||
),
|
|
||||||
validator: (value) =>
|
|
||||||
value == null || value.isEmpty ? 'Required Email' : null,
|
|
||||||
),
|
|
||||||
|
|
||||||
const SizedBox(height: 16),
|
|
||||||
|
|
||||||
/// **Password Field**
|
|
||||||
_buildLabel("Password"),
|
|
||||||
TextFormField(
|
|
||||||
controller: _passwordController,
|
|
||||||
style: TextStyle(
|
|
||||||
fontFamily: "Archivo",
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
fontSize: 11),
|
|
||||||
obscureText: _obscureText,
|
|
||||||
decoration: _inputDecoration("Enter your password").copyWith(
|
|
||||||
prefixIcon: Icon(
|
|
||||||
Icons.key,
|
|
||||||
size: 16,
|
|
||||||
),
|
|
||||||
suffixIcon: IconButton(
|
|
||||||
icon: Icon(
|
|
||||||
_obscureText ? Icons.visibility_off : Icons.visibility,
|
|
||||||
color: Color(0xFF12B24B),
|
|
||||||
size: 16,
|
size: 16,
|
||||||
),
|
),
|
||||||
onPressed: () => setState(() => _obscureText = !_obscureText),
|
|
||||||
),
|
),
|
||||||
|
validator: (value) =>
|
||||||
|
value == null || value.isEmpty ? 'Required Email' : null,
|
||||||
),
|
),
|
||||||
validator: (value) =>
|
|
||||||
value == null || value.isEmpty ? 'Required Password' : null,
|
|
||||||
),
|
|
||||||
|
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 16),
|
||||||
|
|
||||||
/// **Login Button**
|
/// **Password Field**
|
||||||
Row(
|
_buildLabel("Password"),
|
||||||
children: [
|
TextFormField(
|
||||||
Expanded(
|
controller: _passwordController,
|
||||||
child: ElevatedButton(
|
style: TextStyle(
|
||||||
onPressed: () => _login(context),
|
fontFamily: "Archivo",
|
||||||
style: ElevatedButton.styleFrom(
|
fontWeight: FontWeight.w600,
|
||||||
backgroundColor: Color(0xFF12B24B), // Button color
|
fontSize: 11),
|
||||||
foregroundColor: Colors.white, // Text color
|
obscureText: _obscureText,
|
||||||
padding: const EdgeInsets.symmetric(
|
decoration: _inputDecoration("Enter your password").copyWith(
|
||||||
horizontal: 24, vertical: 12),
|
prefixIcon: Icon(
|
||||||
shape: RoundedRectangleBorder(
|
Icons.key,
|
||||||
borderRadius: BorderRadius.circular(18)),
|
size: 16,
|
||||||
|
),
|
||||||
|
suffixIcon: IconButton(
|
||||||
|
icon: Icon(
|
||||||
|
_obscureText ? Icons.visibility_off : Icons.visibility,
|
||||||
|
color: Color(0xFF12B24B),
|
||||||
|
size: 16,
|
||||||
),
|
),
|
||||||
child: Padding(
|
onPressed: () =>
|
||||||
padding: const EdgeInsets.symmetric(
|
setState(() => _obscureText = !_obscureText),
|
||||||
horizontal: 24, vertical: 10),
|
),
|
||||||
child: Row(
|
),
|
||||||
mainAxisSize: MainAxisSize.min,
|
validator: (value) =>
|
||||||
children: [
|
value == null || value.isEmpty ? 'Required Password' : null,
|
||||||
Text(
|
),
|
||||||
"Sign In",
|
|
||||||
style: TextStyle(
|
const SizedBox(height: 20),
|
||||||
fontFamily: "Nunito",
|
|
||||||
fontWeight: FontWeight.w800,
|
/// **Login Button**
|
||||||
fontSize: 15),
|
Row(
|
||||||
),
|
children: [
|
||||||
SizedBox(
|
Expanded(
|
||||||
width: 3,
|
child: ElevatedButton(
|
||||||
),
|
onPressed: () => _login(context),
|
||||||
Icon(
|
style: ElevatedButton.styleFrom(
|
||||||
Icons.arrow_forward_sharp,
|
backgroundColor: Color(0xFF12B24B), // Button color
|
||||||
color: Colors.white,
|
foregroundColor: Colors.white, // Text color
|
||||||
)
|
padding: const EdgeInsets.symmetric(
|
||||||
],
|
horizontal: 24, vertical: 12),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(18)),
|
||||||
|
),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 24, vertical: 10),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Sign In",
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: "Nunito",
|
||||||
|
fontWeight: FontWeight.w800,
|
||||||
|
fontSize: 15),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 3,
|
||||||
|
),
|
||||||
|
Icon(
|
||||||
|
Icons.arrow_forward_sharp,
|
||||||
|
color: Colors.white,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
] else if (_isForgotPassword && !_showOtpResetFields) ...[
|
||||||
const SizedBox(height: 20),
|
_buildLabel("Email Address"),
|
||||||
Center(
|
TextFormField(
|
||||||
child: Text(
|
controller: _emailController,
|
||||||
"Forgot Password",
|
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 11,
|
fontFamily: "Archivo",
|
||||||
fontWeight: FontWeight.w300,
|
fontWeight: FontWeight.w600,
|
||||||
fontFamily: "Nunito",
|
fontSize: 11),
|
||||||
color: Color(0xFF212121), // Text color
|
decoration:
|
||||||
decoration: TextDecoration.underline, // Underline the text
|
_inputDecoration("Enter your email address").copyWith(
|
||||||
|
prefixIcon: Icon(
|
||||||
|
Icons.email_outlined,
|
||||||
|
size: 16,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
validator: (value) =>
|
||||||
|
value == null || value.isEmpty ? 'Required Email' : null,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: ElevatedButton(
|
||||||
|
onPressed: () => _onSubmit(context),
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: Color(0xFF12B24B), // Button color
|
||||||
|
foregroundColor: Colors.white, // Text color
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 24, vertical: 12),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(18)),
|
||||||
|
),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 24, vertical: 10),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Submit",
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: "Nunito",
|
||||||
|
fontWeight: FontWeight.w800,
|
||||||
|
fontSize: 15),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 3,
|
||||||
|
),
|
||||||
|
Icon(
|
||||||
|
Icons.arrow_forward_sharp,
|
||||||
|
color: Colors.white,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
] else ...[
|
||||||
|
_buildLabel("Email Address"),
|
||||||
|
TextFormField(
|
||||||
|
controller: _emailController,
|
||||||
|
readOnly: true,
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: "Archivo",
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
fontSize: 11),
|
||||||
|
decoration:
|
||||||
|
_inputDecoration("Enter your email address").copyWith(
|
||||||
|
prefixIcon: Icon(
|
||||||
|
Icons.email_outlined,
|
||||||
|
size: 16,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
validator: (value) =>
|
||||||
|
value == null || value.isEmpty ? 'Required Email' : null,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
_buildLabel("OTP"),
|
||||||
|
TextFormField(
|
||||||
|
controller: _otpController,
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: "Archivo",
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
fontSize: 11),
|
||||||
|
decoration: _inputDecoration("Enter your OTP").copyWith(
|
||||||
|
prefixIcon: Icon(
|
||||||
|
Icons.email_outlined,
|
||||||
|
size: 16,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
validator: (value) =>
|
||||||
|
value == null || value.isEmpty ? 'Required OTP' : null,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
_buildLabel("New Password"),
|
||||||
|
TextFormField(
|
||||||
|
controller: _newPasswordController,
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: "Archivo",
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
fontSize: 11),
|
||||||
|
obscureText: _obscureText,
|
||||||
|
decoration:
|
||||||
|
_inputDecoration("Enter your new password").copyWith(
|
||||||
|
prefixIcon: Icon(
|
||||||
|
Icons.key,
|
||||||
|
size: 16,
|
||||||
|
),
|
||||||
|
suffixIcon: IconButton(
|
||||||
|
icon: Icon(
|
||||||
|
_obscureText ? Icons.visibility_off : Icons.visibility,
|
||||||
|
color: Color(0xFF12B24B),
|
||||||
|
size: 16,
|
||||||
|
),
|
||||||
|
onPressed: () =>
|
||||||
|
setState(() => _obscureText = !_obscureText),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
validator: (value) => value == null || value.isEmpty
|
||||||
|
? 'Required New Password'
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
_buildLabel("Confirm Password"),
|
||||||
|
TextFormField(
|
||||||
|
controller: _confirmPasswordController,
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: "Archivo",
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
fontSize: 11),
|
||||||
|
obscureText: _obscureText,
|
||||||
|
decoration:
|
||||||
|
_inputDecoration("Enter your confirm password").copyWith(
|
||||||
|
prefixIcon: Icon(
|
||||||
|
Icons.key,
|
||||||
|
size: 16,
|
||||||
|
),
|
||||||
|
suffixIcon: IconButton(
|
||||||
|
icon: Icon(
|
||||||
|
_obscureText ? Icons.visibility_off : Icons.visibility,
|
||||||
|
color: Color(0xFF12B24B),
|
||||||
|
size: 16,
|
||||||
|
),
|
||||||
|
onPressed: () =>
|
||||||
|
setState(() => _obscureText = !_obscureText),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
validator: (value) {
|
||||||
|
if (value == null || value.isEmpty) {
|
||||||
|
return 'Required New Password';
|
||||||
|
}
|
||||||
|
if (value != _newPasswordController.text) {
|
||||||
|
return 'Passwords do not match';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
if (!_formKey.currentState!.validate()) return;
|
||||||
|
setState(() {
|
||||||
|
_isForgotPassword = false;
|
||||||
|
_showOtpResetFields = true;
|
||||||
|
_passwordController.clear();
|
||||||
|
});
|
||||||
|
_onSubmit(context);
|
||||||
|
},
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: Color(0xFF12B24B), // Button color
|
||||||
|
foregroundColor: Colors.white, // Text color
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 24, vertical: 12),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(18)),
|
||||||
|
),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 24, vertical: 10),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Submit",
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: "Nunito",
|
||||||
|
fontWeight: FontWeight.w800,
|
||||||
|
fontSize: 15),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 3,
|
||||||
|
),
|
||||||
|
Icon(
|
||||||
|
Icons.arrow_forward_sharp,
|
||||||
|
color: Colors.white,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
if (!_isForgotPassword && !_showOtpResetFields)
|
||||||
|
Center(
|
||||||
|
child: TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
_isForgotPassword = true;
|
||||||
|
_showOtpResetFields = false;
|
||||||
|
_passwordController.clear();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: Text(
|
||||||
|
"Forgot Password",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 11,
|
||||||
|
fontWeight: FontWeight.w300,
|
||||||
|
fontFamily: "Nunito",
|
||||||
|
color: Color(0xFF212121), // Text color
|
||||||
|
decoration:
|
||||||
|
TextDecoration.underline, // Underline the text
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
if (_isForgotPassword || _showOtpResetFields)
|
||||||
|
Center(
|
||||||
const SizedBox(height: 20),
|
child: TextButton(
|
||||||
|
onPressed: () {
|
||||||
Container(
|
setState(() {
|
||||||
width: 45, // Adjust size
|
_isForgotPassword = false;
|
||||||
height: 45,
|
_showOtpResetFields = false;
|
||||||
decoration: BoxDecoration(
|
_clearAllFields();
|
||||||
// Background color
|
});
|
||||||
shape: BoxShape.rectangle,
|
},
|
||||||
borderRadius: BorderRadius.all(Radius.circular(15)),
|
child: Text(
|
||||||
border: Border.all(
|
"Back to Login",
|
||||||
color: Color(0xFF9E9DBD), width: 1), // Grey outline
|
style: TextStyle(
|
||||||
|
fontSize: 11,
|
||||||
|
fontWeight: FontWeight.w300,
|
||||||
|
fontFamily: "Nunito",
|
||||||
|
color: Color(0xFF212121), // Text color
|
||||||
|
decoration:
|
||||||
|
TextDecoration.underline, // Underline the text
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
child: Center(
|
const SizedBox(height: 20),
|
||||||
child: Image.asset(
|
if (!_isForgotPassword && !_showOtpResetFields)
|
||||||
'assets/images/login/VectorG.png',
|
Container(
|
||||||
width: 20, // Optional: control size
|
width: 45, // Adjust size
|
||||||
height: 10,
|
height: 45,
|
||||||
fit: BoxFit.contain,
|
decoration: BoxDecoration(
|
||||||
)),
|
// Background color
|
||||||
),
|
shape: BoxShape.rectangle,
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(15)),
|
||||||
|
border: Border.all(
|
||||||
|
color: Color(0xFF9E9DBD), width: 1), // Grey outline
|
||||||
|
),
|
||||||
|
|
||||||
|
child: Center(
|
||||||
|
child: Image.asset(
|
||||||
|
'assets/images/login/VectorG.png',
|
||||||
|
width: 20, // Optional: control size
|
||||||
|
height: 10,
|
||||||
|
fit: BoxFit.contain,
|
||||||
|
)),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -466,7 +466,7 @@ PopupMenuItem<String> buildMenuItem(Map<String, dynamic> item) {
|
|||||||
item['label'],
|
item['label'],
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
fontFamily: "Roboto",
|
fontFamily: "Inter",
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
color: Colors.black87,
|
color: Colors.black87,
|
||||||
),
|
),
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user