formatted all files.

This commit is contained in:
Faris Armoush
2025-06-12 15:33:32 +03:00
parent 29959f567e
commit 04250ebc98
474 changed files with 5425 additions and 4338 deletions

View File

@ -36,7 +36,8 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
////////////////////////////// forget password //////////////////////////////////
final TextEditingController forgetEmailController = TextEditingController();
final TextEditingController forgetPasswordController = TextEditingController();
final TextEditingController forgetPasswordController =
TextEditingController();
final TextEditingController forgetOtp = TextEditingController();
final forgetFormKey = GlobalKey<FormState>();
final forgetEmailKey = GlobalKey<FormState>();
@ -53,7 +54,8 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
return;
}
_remainingTime = 1;
add(UpdateTimerEvent(remainingTime: _remainingTime, isButtonEnabled: false));
add(UpdateTimerEvent(
remainingTime: _remainingTime, isButtonEnabled: false));
try {
forgetEmailValidate = '';
_remainingTime = (await AuthenticationAPI.sendOtp(
@ -62,7 +64,7 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
} on DioException catch (e) {
if (e.response!.statusCode == 400) {
final errorData = e.response!.data;
String errorMessage = errorData['message'];
final String errorMessage = errorData['message'];
if (errorMessage == 'User not found') {
validate = 'Invalid Credential';
emit(AuthInitialState());
@ -90,7 +92,8 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
_timer?.cancel();
add(const UpdateTimerEvent(remainingTime: 0, isButtonEnabled: true));
} else {
add(UpdateTimerEvent(remainingTime: _remainingTime, isButtonEnabled: false));
add(UpdateTimerEvent(
remainingTime: _remainingTime, isButtonEnabled: false));
}
});
}
@ -100,11 +103,11 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
emit(const TimerState(isButtonEnabled: true, remainingTime: 0));
}
Future<void> changePassword(
Future<void> changePassword(
ChangePasswordEvent event, Emitter<AuthState> emit) async {
emit(LoadingForgetState());
try {
var response = await AuthenticationAPI.verifyOtp(
final response = await AuthenticationAPI.verifyOtp(
email: forgetEmailController.text, otpCode: forgetOtp.text);
if (response == true) {
await AuthenticationAPI.forgetPassword(
@ -122,7 +125,6 @@ Future<void> changePassword(
}
}
String? validateCode(String? value) {
if (value == null || value.isEmpty) {
return 'Code is required';
@ -131,7 +133,9 @@ Future<void> changePassword(
}
void _onUpdateTimer(UpdateTimerEvent event, Emitter<AuthState> emit) {
emit(TimerState(isButtonEnabled: event.isButtonEnabled, remainingTime: event.remainingTime));
emit(TimerState(
isButtonEnabled: event.isButtonEnabled,
remainingTime: event.remainingTime));
}
///////////////////////////////////// login /////////////////////////////////////
@ -151,8 +155,7 @@ Future<void> changePassword(
static UserModel? user;
bool showValidationMessage = false;
void _login(LoginButtonPressed event, Emitter<AuthState> emit) async {
Future<void> _login(LoginButtonPressed event, Emitter<AuthState> emit) async {
emit(AuthLoading());
if (isChecked) {
try {
@ -179,7 +182,7 @@ Future<void> changePassword(
}
if (token.accessTokenIsNotEmpty) {
FlutterSecureStorage storage = const FlutterSecureStorage();
const storage = FlutterSecureStorage();
await storage.write(
key: Token.loginAccessTokenKey, value: token.accessToken);
const FlutterSecureStorage().write(
@ -197,8 +200,7 @@ Future<void> changePassword(
}
}
checkBoxToggle(
void checkBoxToggle(
CheckBoxEvent event,
Emitter<AuthState> emit,
) {
@ -277,12 +279,12 @@ Future<void> changePassword(
if (value == null || value.isEmpty) {
return 'Please enter your password';
}
List<String> validationErrors = [];
final validationErrors = <String>[];
if (!RegExp(r'^(?=.*[a-z])').hasMatch(value)) {
if (!RegExp('^(?=.*[a-z])').hasMatch(value)) {
validationErrors.add(' - one lowercase letter');
}
if (!RegExp(r'^(?=.*[A-Z])').hasMatch(value)) {
if (!RegExp('^(?=.*[A-Z])').hasMatch(value)) {
validationErrors.add(' - one uppercase letter');
}
if (!RegExp(r'^(?=.*\d)').hasMatch(value)) {
@ -304,7 +306,7 @@ Future<void> changePassword(
String? fullNameValidator(String? value) {
if (value == null) return 'Full name is required';
final withoutExtraSpaces = value.replaceAll(RegExp(r"\s+"), ' ').trim();
final withoutExtraSpaces = value.replaceAll(RegExp(r'\s+'), ' ').trim();
if (withoutExtraSpaces.length < 2 || withoutExtraSpaces.length > 30) {
return 'Full name must be between 2 and 30 characters long';
}
@ -339,12 +341,14 @@ Future<void> changePassword(
static Future<String> getTokenAndValidate() async {
try {
const storage = FlutterSecureStorage();
final firstLaunch =
await SharedPreferencesHelper.readBoolFromSP(StringsManager.firstLaunch) ?? true;
final firstLaunch = await SharedPreferencesHelper.readBoolFromSP(
StringsManager.firstLaunch) ??
true;
if (firstLaunch) {
storage.deleteAll();
}
await SharedPreferencesHelper.saveBoolToSP(StringsManager.firstLaunch, false);
await SharedPreferencesHelper.saveBoolToSP(
StringsManager.firstLaunch, false);
final value = await storage.read(key: Token.loginAccessTokenKey) ?? '';
if (value.isEmpty) {
return 'Token not found';
@ -366,7 +370,8 @@ Future<void> changePassword(
}
}
void _fetchRegion(RegionInitialEvent event, Emitter<AuthState> emit) async {
Future<void> _fetchRegion(
RegionInitialEvent event, Emitter<AuthState> emit) async {
try {
emit(AuthLoading());
regionList = await AuthenticationAPI.fetchRegion();
@ -389,15 +394,17 @@ Future<void> changePassword(
}
String formattedTime(int time) {
final int days = (time / 86400).floor(); // 86400 seconds in a day
final int hours = ((time % 86400) / 3600).floor();
final int minutes = (((time % 86400) % 3600) / 60).floor();
final int seconds = (((time % 86400) % 3600) % 60).floor();
final days = (time / 86400).floor(); // 86400 seconds in a day
final hours = ((time % 86400) / 3600).floor();
final minutes = (((time % 86400) % 3600) / 60).floor();
final seconds = ((time % 86400) % 3600) % 60;
final String formattedTime = [
final formattedTime = [
if (days > 0) '${days}d', // Append 'd' for days
if (days > 0 || hours > 0)
hours.toString().padLeft(2, '0'), // Show hours if there are days or hours
hours
.toString()
.padLeft(2, '0'), // Show hours if there are days or hours
minutes.toString().padLeft(2, '0'),
seconds.toString().padLeft(2, '0'),
].join(':');
@ -417,7 +424,7 @@ Future<void> changePassword(
return checkValidate;
}
changeValidate(
void changeValidate(
ChangeValidateEvent event,
Emitter<AuthState> emit,
) {
@ -426,7 +433,7 @@ Future<void> changePassword(
emit(LoginInitial());
}
changeForgetValidate(
void changeForgetValidate(
ChangeValidateEvent event,
Emitter<AuthState> emit,
) {

View File

@ -46,7 +46,8 @@ class StopTimerEvent extends AuthEvent {}
class UpdateTimerEvent extends AuthEvent {
final int remainingTime;
final bool isButtonEnabled;
const UpdateTimerEvent({required this.remainingTime, required this.isButtonEnabled});
const UpdateTimerEvent(
{required this.remainingTime, required this.isButtonEnabled});
}
class ChangePasswordEvent extends AuthEvent {}

View File

@ -56,7 +56,8 @@ class TimerState extends AuthState {
final bool isButtonEnabled;
final int remainingTime;
const TimerState({required this.isButtonEnabled, required this.remainingTime});
const TimerState(
{required this.isButtonEnabled, required this.remainingTime});
@override
List<Object> get props => [isButtonEnabled, remainingTime];
@ -80,7 +81,7 @@ class TimerUpdated extends AuthState {
final String formattedTime;
final bool isButtonEnabled;
TimerUpdated({
const TimerUpdated({
required this.formattedTime,
required this.isButtonEnabled,
});

View File

@ -21,9 +21,9 @@ class LoginWithEmailModel {
return {
'email': email,
'password': password,
"platform": "web"
'platform': 'web'
// 'regionUuid': regionUuid,
};
}
}
//tst@tst.com
//tst@tst.com

View File

@ -11,6 +11,14 @@ class Token {
final int iat;
final int exp;
Token(
this.accessToken,
this.refreshToken,
this.sessionId,
this.iat,
this.exp,
);
Token.emptyConstructor()
: accessToken = '',
refreshToken = '',
@ -24,14 +32,6 @@ class Token {
bool get isNotEmpty => accessToken.isNotEmpty && refreshToken.isNotEmpty;
Token(
this.accessToken,
this.refreshToken,
this.sessionId,
this.iat,
this.exp,
);
Token.refreshToken(this.refreshToken)
: accessToken = '',
sessionId = '',
@ -40,7 +40,7 @@ class Token {
factory Token.fromJson(Map<String, dynamic> json) {
//save token to secure storage
var storage = const FlutterSecureStorage();
const storage = FlutterSecureStorage();
storage.write(
key: loginAccessTokenKey, value: json[loginAccessTokenKey] ?? '');
storage.write(

View File

@ -55,22 +55,21 @@ class UserModel {
//from token
factory UserModel.fromToken(Token token) {
Map<String, dynamic> tempJson = Token.decodeToken(token.accessToken);
final tempJson = Token.decodeToken(token.accessToken);
return UserModel(
hasAcceptedWebAgreement: null,
role: null,
webAgreementAcceptedAt: null,
uuid: tempJson['uuid'].toString(),
email: tempJson['email'],
firstName: null,
lastName: null,
photoUrl: null,
phoneNumber: null,
isEmailVerified: null,
isAgreementAccepted: null,
project: null
);
hasAcceptedWebAgreement: null,
role: null,
webAgreementAcceptedAt: null,
uuid: tempJson['uuid'].toString(),
email: tempJson['email'],
firstName: null,
lastName: null,
photoUrl: null,
phoneNumber: null,
isEmailVerified: null,
isAgreementAccepted: null,
project: null);
}
Map<String, dynamic> toJson() {

View File

@ -36,20 +36,18 @@ class ForgetPasswordWebPage extends StatelessWidget {
);
}
},
builder: (context, state) {
return _buildForm(context, state);
},
builder: _buildForm,
),
),
);
}
Widget _buildForm(BuildContext context, AuthState state) {
late ScrollController _scrollController;
_scrollController = ScrollController();
void _scrollToCenter() {
final double middlePosition = _scrollController.position.maxScrollExtent / 2;
_scrollController.animateTo(
late ScrollController scrollController;
scrollController = ScrollController();
void scrollToCenter() {
final middlePosition = scrollController.position.maxScrollExtent / 2;
scrollController.animateTo(
middlePosition,
duration: const Duration(seconds: 1),
curve: Curves.easeInOut,
@ -57,24 +55,25 @@ class ForgetPasswordWebPage extends StatelessWidget {
}
WidgetsBinding.instance.addPostFrameCallback((_) {
_scrollToCenter();
scrollToCenter();
});
final forgetBloc = BlocProvider.of<AuthBloc>(context);
Size size = MediaQuery.of(context).size;
final size = MediaQuery.of(context).size;
return FirstLayer(
second: Center(
child: Stack(
children: [
if (state is AuthLoading) const Center(child: CircularProgressIndicator()),
if (state is AuthLoading)
const Center(child: CircularProgressIndicator()),
ListView(
shrinkWrap: true,
controller: _scrollController,
controller: scrollController,
children: [
Container(
padding: EdgeInsets.all(size.width * 0.02),
margin: EdgeInsets.all(size.width * 0.09),
decoration: BoxDecoration(
color: Colors.black.withOpacity(0.3),
color: Colors.black.withValues(alpha: 0.3),
borderRadius: const BorderRadius.all(Radius.circular(20)),
),
child: Center(
@ -94,17 +93,22 @@ class ForgetPasswordWebPage extends StatelessWidget {
flex: 3,
child: Container(
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.1),
borderRadius: const BorderRadius.all(Radius.circular(30)),
border: Border.all(color: ColorsManager.graysColor.withOpacity(0.2)),
color: Colors.white.withValues(alpha: 0.1),
borderRadius:
const BorderRadius.all(Radius.circular(30)),
border: Border.all(
color: ColorsManager.graysColor
.withValues(alpha: 0.2)),
),
child: Form(
key: forgetBloc.forgetFormKey,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: size.width * 0.02, vertical: size.width * 0.003),
horizontal: size.width * 0.02,
vertical: size.width * 0.003),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
const SizedBox(height: 10),
@ -121,7 +125,9 @@ class ForgetPasswordWebPage extends StatelessWidget {
style: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(fontSize: 14, fontWeight: FontWeight.w400),
.copyWith(
fontSize: 14,
fontWeight: FontWeight.w400),
),
const SizedBox(height: 10),
// Column(
@ -140,69 +146,90 @@ class ForgetPasswordWebPage extends StatelessWidget {
Form(
key: forgetBloc.forgetEmailKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
mainAxisAlignment:
MainAxisAlignment.start,
children: [
Text(
"Account",
style: Theme.of(context).textTheme.bodySmall!.copyWith(
fontSize: 14, fontWeight: FontWeight.w400),
'Account',
style: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(
fontSize: 14,
fontWeight:
FontWeight.w400),
),
const SizedBox(height: 10),
SizedBox(
child: TextFormField(
controller: forgetBloc.forgetEmailController,
validator: forgetBloc.validateEmail,
decoration: textBoxDecoration()!.copyWith(
controller: forgetBloc
.forgetEmailController,
validator:
forgetBloc.validateEmail,
decoration:
textBoxDecoration()!.copyWith(
hintText: 'Enter your email',
hintStyle: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(
color: ColorsManager.grayColor,
fontWeight: FontWeight.w400),
color: ColorsManager
.grayColor,
fontWeight:
FontWeight.w400),
),
style: const TextStyle(color: Colors.black),
style: const TextStyle(
color: Colors.black),
),
),
],
)),
const SizedBox(height: 20.0),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
"One Time Password",
'One Time Password',
style: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(fontSize: 14, fontWeight: FontWeight.w400),
.copyWith(
fontSize: 14,
fontWeight: FontWeight.w400),
),
const SizedBox(height: 10),
SizedBox(
child: TextFormField(
validator: forgetBloc.validateCode,
keyboardType: TextInputType.visiblePassword,
keyboardType:
TextInputType.visiblePassword,
controller: forgetBloc.forgetOtp,
decoration: textBoxDecoration()!.copyWith(
decoration:
textBoxDecoration()!.copyWith(
hintText: 'Enter Code',
hintStyle: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(
color: ColorsManager.grayColor,
fontWeight: FontWeight.w400),
color:
ColorsManager.grayColor,
fontWeight:
FontWeight.w400),
suffixIcon: SizedBox(
width: 100,
child: Center(
child: InkWell(
onTap: state is TimerState &&
!state.isButtonEnabled &&
state.remainingTime != 1
!state
.isButtonEnabled &&
state.remainingTime !=
1
? null
:
() {
: () {
if (forgetBloc
.forgetEmailKey
.currentState!
@ -211,27 +238,31 @@ class ForgetPasswordWebPage extends StatelessWidget {
StartTimerEvent());
}
},
child: Text(
'Get Code ${state is TimerState && !state.isButtonEnabled && state.remainingTime != 1 ? "(${forgetBloc.formattedTime(state.remainingTime)}) " : ""}',
style: TextStyle(
color: state is TimerState &&
!state.isButtonEnabled
color: state
is TimerState &&
!state
.isButtonEnabled
? Colors.grey
: ColorsManager.btnColor,
: ColorsManager
.btnColor,
),
),
),
),
),
),
style: const TextStyle(color: Colors.black),
style: const TextStyle(
color: Colors.black),
),
),
if (forgetBloc.forgetValidate !=
'') // Check if there is a validation message
Padding(
padding: const EdgeInsets.only(top: 8.0),
padding:
const EdgeInsets.only(top: 8.0),
child: Text(
forgetBloc.forgetValidate,
style: const TextStyle(
@ -244,34 +275,44 @@ class ForgetPasswordWebPage extends StatelessWidget {
),
const SizedBox(height: 20.0),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
"Password",
'Password',
style: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(fontSize: 14, fontWeight: FontWeight.w400),
.copyWith(
fontSize: 14,
fontWeight: FontWeight.w400),
),
const SizedBox(height: 10),
SizedBox(
child: TextFormField(
obscureText: forgetBloc.obscureText,
keyboardType: TextInputType.visiblePassword,
validator: forgetBloc.passwordValidator,
controller: forgetBloc.forgetPasswordController,
decoration: textBoxDecoration()!.copyWith(
keyboardType:
TextInputType.visiblePassword,
validator:
forgetBloc.passwordValidator,
controller: forgetBloc
.forgetPasswordController,
decoration:
textBoxDecoration()!.copyWith(
suffixIcon: IconButton(
onPressed: () {
forgetBloc.add(PasswordVisibleEvent(
newValue: forgetBloc.obscureText));
forgetBloc.add(
PasswordVisibleEvent(
newValue: forgetBloc
.obscureText));
},
icon: SizedBox(
child: SvgPicture.asset(
forgetBloc.obscureText
? Assets.visiblePassword
: Assets.invisiblePassword,
: Assets
.invisiblePassword,
height: 15,
width: 15,
),
@ -282,10 +323,13 @@ class ForgetPasswordWebPage extends StatelessWidget {
.textTheme
.bodySmall!
.copyWith(
color: ColorsManager.grayColor,
fontWeight: FontWeight.w400),
color:
ColorsManager.grayColor,
fontWeight:
FontWeight.w400),
),
style: const TextStyle(color: Colors.black),
style: const TextStyle(
color: Colors.black),
),
),
],
@ -295,23 +339,31 @@ class ForgetPasswordWebPage extends StatelessWidget {
),
const SizedBox(height: 20.0),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
crossAxisAlignment:
CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: size.width * 0.2,
child: DefaultButton(
backgroundColor: ColorsManager.btnColor,
backgroundColor:
ColorsManager.btnColor,
child: const Text('Submit'),
onPressed: () {
if (forgetBloc.forgetFormKey.currentState!.validate() ||
forgetBloc.forgetEmailKey.currentState!
if (forgetBloc
.forgetFormKey.currentState!
.validate() ||
forgetBloc.forgetEmailKey
.currentState!
.validate()) {
if (forgetBloc.forgetEmailKey.currentState!
if (forgetBloc.forgetEmailKey
.currentState!
.validate() &&
forgetBloc.forgetFormKey.currentState!
forgetBloc.forgetFormKey
.currentState!
.validate()) {
forgetBloc.add(ChangePasswordEvent());
forgetBloc
.add(ChangePasswordEvent());
}
}
},
@ -325,7 +377,8 @@ class ForgetPasswordWebPage extends StatelessWidget {
child: Text(
forgetBloc.validate,
style: const TextStyle(
fontWeight: FontWeight.w700, color: ColorsManager.red),
fontWeight: FontWeight.w700,
color: ColorsManager.red),
),
),
),
@ -337,8 +390,9 @@ class ForgetPasswordWebPage extends StatelessWidget {
child: Wrap(
children: [
const Text(
"Do you have an account? ",
style: TextStyle(color: Colors.white),
'Do you have an account? ',
style:
TextStyle(color: Colors.white),
),
InkWell(
onTap: () {
@ -346,7 +400,7 @@ class ForgetPasswordWebPage extends StatelessWidget {
Navigator.pop(context);
},
child: const Text(
"Sign in",
'Sign in',
),
),
],
@ -372,14 +426,15 @@ class ForgetPasswordWebPage extends StatelessWidget {
));
}
Widget _buildDropdownField(BuildContext context, AuthBloc loginBloc, Size size) {
final TextEditingController textEditingController = TextEditingController();
Widget _buildDropdownField(
BuildContext context, AuthBloc loginBloc, Size size) {
final textEditingController = TextEditingController();
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
"Country/Region",
'Country/Region',
style: Theme.of(context).textTheme.bodySmall!.copyWith(
fontSize: 14,
fontWeight: FontWeight.w400,
@ -398,10 +453,13 @@ class ForgetPasswordWebPage extends StatelessWidget {
builder: (FormFieldState<String> field) {
return InputDecorator(
decoration: InputDecoration(
contentPadding: const EdgeInsets.symmetric(horizontal: 2, vertical: 10),
contentPadding:
const EdgeInsets.symmetric(horizontal: 2, vertical: 10),
errorText: field.errorText,
filled: true, // Ensure the dropdown is filled with the background color
fillColor: ColorsManager.boxColor, // Match the dropdown container color
filled:
true, // Ensure the dropdown is filled with the background color
fillColor: ColorsManager
.boxColor, // Match the dropdown container color
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide(
@ -412,14 +470,16 @@ class ForgetPasswordWebPage extends StatelessWidget {
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide(
color: field.hasError ? Colors.red : ColorsManager.grayColor,
color:
field.hasError ? Colors.red : ColorsManager.grayColor,
width: 1.5,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide(
color: field.hasError ? Colors.red : ColorsManager.grayColor,
color:
field.hasError ? Colors.red : ColorsManager.grayColor,
width: 1.5,
),
),
@ -446,10 +506,11 @@ class ForgetPasswordWebPage extends StatelessWidget {
return DropdownMenuItem<String>(
value: region.id,
child: Text(
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: 14,
fontWeight: FontWeight.w400,
),
style:
Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: 14,
fontWeight: FontWeight.w400,
),
region.name,
overflow: TextOverflow.ellipsis,
maxLines: 1,
@ -462,7 +523,8 @@ class ForgetPasswordWebPage extends StatelessWidget {
onChanged: (String? value) {
if (value != null) {
loginBloc.add(SelectRegionEvent(val: value));
field.didChange(value); // Notify the form field of the change
field.didChange(
value); // Notify the form field of the change
}
},
buttonStyleData: const ButtonStyleData(
@ -486,7 +548,8 @@ class ForgetPasswordWebPage extends StatelessWidget {
searchInnerWidgetHeight: 50,
searchInnerWidget: Container(
height: 50,
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
padding: const EdgeInsets.symmetric(
horizontal: 8, vertical: 4),
child: TextFormField(
style: const TextStyle(color: Colors.black),
controller: textEditingController,
@ -500,7 +563,8 @@ class ForgetPasswordWebPage extends StatelessWidget {
),
),
searchMatchFn: (item, searchValue) {
final regionName = (item.child as Text).data?.toLowerCase() ?? '';
final regionName =
(item.child as Text).data?.toLowerCase() ?? '';
final search = searchValue.toLowerCase().trim();
return regionName.contains(search);
},

View File

@ -79,7 +79,7 @@ class LoginMobilePage extends StatelessWidget {
child: Container(
margin: const EdgeInsets.all(50),
decoration: BoxDecoration(
color: Colors.black.withOpacity(0.3),
color: Colors.black.withValues(alpha: 0.3),
borderRadius: const BorderRadius.all(Radius.circular(20))),
child: Column(
mainAxisSize: MainAxisSize.min,
@ -93,12 +93,15 @@ class LoginMobilePage extends StatelessWidget {
),
),
Container(
margin: EdgeInsets.all(30),
padding: EdgeInsets.all(20),
margin: const EdgeInsets.all(30),
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.1),
borderRadius: const BorderRadius.all(Radius.circular(30)),
border: Border.all(color: ColorsManager.graysColor.withOpacity(0.2))),
color: Colors.white.withValues(alpha: 0.1),
borderRadius:
const BorderRadius.all(Radius.circular(30)),
border: Border.all(
color: ColorsManager.graysColor
.withValues(alpha: 0.2))),
child: Form(
key: loginBloc.loginFormKey,
child: Column(
@ -109,7 +112,9 @@ class LoginMobilePage extends StatelessWidget {
const Text(
'Login',
style: TextStyle(
color: Colors.white, fontSize: 24, fontWeight: FontWeight.bold),
color: Colors.white,
fontSize: 24,
fontWeight: FontWeight.bold),
),
const SizedBox(height: 30),
// Column(
@ -155,15 +160,15 @@ class LoginMobilePage extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
"Email",
'Email',
style: Theme.of(context).textTheme.bodySmall,
),
SizedBox(
child: TextFormField(
validator: loginBloc.validateEmail,
controller: loginBloc.loginEmailController,
decoration:
textBoxDecoration()!.copyWith(hintText: 'Enter your email'),
decoration: textBoxDecoration()!
.copyWith(hintText: 'Enter your email'),
style: const TextStyle(color: Colors.black),
),
),
@ -175,7 +180,7 @@ class LoginMobilePage extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
"Password",
'Password',
style: Theme.of(context).textTheme.bodySmall,
),
SizedBox(
@ -183,7 +188,8 @@ class LoginMobilePage extends StatelessWidget {
validator: loginBloc.validatePassword,
obscureText: loginBloc.obscureText,
keyboardType: TextInputType.visiblePassword,
controller: loginBloc.loginPasswordController,
controller:
loginBloc.loginPasswordController,
decoration: textBoxDecoration()!.copyWith(
hintText: 'At least 8 characters',
),
@ -201,16 +207,19 @@ class LoginMobilePage extends StatelessWidget {
children: [
InkWell(
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => const ForgetPasswordPage(),
Navigator.of(context)
.push(MaterialPageRoute(
builder: (context) =>
const ForgetPasswordPage(),
));
},
child: Text(
"Forgot Password?",
'Forgot Password?',
style: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(color: ColorsManager.blackColor),
.copyWith(
color: ColorsManager.blackColor),
),
),
],
@ -221,13 +230,15 @@ class LoginMobilePage extends StatelessWidget {
Transform.scale(
scale: 1.2, // Adjust the scale as needed
child: Checkbox(
fillColor: MaterialStateProperty.all<Color>(Colors.white),
fillColor: WidgetStateProperty.all<Color>(
Colors.white),
activeColor: Colors.white,
value: loginBloc.isChecked,
checkColor: Colors.black,
shape: const CircleBorder(),
onChanged: (bool? newValue) {
loginBloc.add(CheckBoxEvent(newValue: newValue));
loginBloc.add(
CheckBoxEvent(newValue: newValue));
},
),
),
@ -236,30 +247,37 @@ class LoginMobilePage extends StatelessWidget {
child: RichText(
text: TextSpan(
text: 'Agree to ',
style: const TextStyle(color: Colors.white),
style:
const TextStyle(color: Colors.white),
children: [
TextSpan(
text: '(Terms of Service)',
style: const TextStyle(color: Colors.black),
style: const TextStyle(
color: Colors.black),
recognizer: TapGestureRecognizer()
..onTap = () {
loginBloc.launchURL('https://example.com/terms');
loginBloc.launchURL(
'https://example.com/terms');
},
),
TextSpan(
text: ' (Legal Statement)',
style: const TextStyle(color: Colors.black),
style: const TextStyle(
color: Colors.black),
recognizer: TapGestureRecognizer()
..onTap = () {
loginBloc.launchURL('https://example.com/legal');
loginBloc.launchURL(
'https://example.com/legal');
},
),
TextSpan(
text: ' (Privacy Statement)',
style: const TextStyle(color: Colors.black),
style: const TextStyle(
color: Colors.black),
recognizer: TapGestureRecognizer()
..onTap = () {
loginBloc.launchURL('https://example.com/privacy');
loginBloc.launchURL(
'https://example.com/privacy');
},
),
],
@ -276,11 +294,14 @@ class LoginMobilePage extends StatelessWidget {
: ColorsManager.grayColor,
child: const Text('Sign in'),
onPressed: () {
if (loginBloc.loginFormKey.currentState!.validate()) {
if (loginBloc.loginFormKey.currentState!
.validate()) {
loginBloc.add(
LoginButtonPressed(
username: loginBloc.loginEmailController.text,
password: loginBloc.loginPasswordController.text,
username:
loginBloc.loginEmailController.text,
password: loginBloc
.loginPasswordController.text,
),
);
}
@ -295,10 +316,11 @@ class LoginMobilePage extends StatelessWidget {
Flexible(
child: Text(
"Don't you have an account? ",
style: TextStyle(color: Colors.white, fontSize: 13),
style: TextStyle(
color: Colors.white, fontSize: 13),
)),
Text(
"Sign up",
'Sign up',
),
],
),

View File

@ -24,7 +24,8 @@ class LoginWebPage extends StatefulWidget {
State<LoginWebPage> createState() => _LoginWebPageState();
}
class _LoginWebPageState extends State<LoginWebPage> with HelperResponsiveLayout {
class _LoginWebPageState extends State<LoginWebPage>
with HelperResponsiveLayout {
@override
Widget build(BuildContext context) {
return Scaffold(
@ -42,9 +43,7 @@ class _LoginWebPageState extends State<LoginWebPage> with HelperResponsiveLayout
);
}
},
builder: (context, state) {
return _buildLoginForm(context, state);
},
builder: _buildLoginForm,
),
),
);
@ -54,12 +53,12 @@ class _LoginWebPageState extends State<LoginWebPage> with HelperResponsiveLayout
final loginBloc = BlocProvider.of<AuthBloc>(context);
final isSmallScreen = isSmallScreenSize(context);
final isMediumScreen = isMediumScreenSize(context);
Size size = MediaQuery.of(context).size;
final size = MediaQuery.of(context).size;
late ScrollController scrollController;
scrollController = ScrollController();
void scrollToCenter() {
final double middlePosition = scrollController.position.maxScrollExtent / 2;
final middlePosition = scrollController.position.maxScrollExtent / 2;
scrollController.animateTo(
middlePosition,
duration: const Duration(seconds: 1),
@ -84,7 +83,7 @@ class _LoginWebPageState extends State<LoginWebPage> with HelperResponsiveLayout
padding: EdgeInsets.all(size.width * 0.02),
margin: EdgeInsets.all(size.width * 0.05),
decoration: BoxDecoration(
color: Colors.black.withOpacity(0.3),
color: Colors.black.withValues(alpha: 0.3),
borderRadius: const BorderRadius.all(Radius.circular(20)),
),
child: Center(
@ -121,7 +120,8 @@ class _LoginWebPageState extends State<LoginWebPage> with HelperResponsiveLayout
const Spacer(),
Expanded(
flex: 2,
child: _buildLoginFormFields(context, loginBloc, size),
child: _buildLoginFormFields(
context, loginBloc, size),
),
const Spacer(),
],
@ -132,23 +132,26 @@ class _LoginWebPageState extends State<LoginWebPage> with HelperResponsiveLayout
),
),
),
if (state is AuthLoading) const Center(child: CircularProgressIndicator())
if (state is AuthLoading)
const Center(child: CircularProgressIndicator())
],
);
}
Widget _buildLoginFormFields(BuildContext context, AuthBloc loginBloc, Size size) {
Widget _buildLoginFormFields(
BuildContext context, AuthBloc loginBloc, Size size) {
return Container(
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.1),
color: Colors.white.withValues(alpha: 0.1),
borderRadius: const BorderRadius.all(Radius.circular(30)),
border: Border.all(color: ColorsManager.graysColor.withOpacity(0.2)),
border:
Border.all(color: ColorsManager.graysColor.withValues(alpha: 0.2)),
),
child: Form(
key: loginBloc.loginFormKey,
child: Padding(
padding:
EdgeInsets.symmetric(horizontal: size.width * 0.02, vertical: size.width * 0.003),
padding: EdgeInsets.symmetric(
horizontal: size.width * 0.02, vertical: size.width * 0.003),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
@ -176,14 +179,15 @@ class _LoginWebPageState extends State<LoginWebPage> with HelperResponsiveLayout
);
}
Widget _buildDropdownField(BuildContext context, AuthBloc loginBloc, Size size) {
final TextEditingController textEditingController = TextEditingController();
Widget _buildDropdownField(
BuildContext context, AuthBloc loginBloc, Size size) {
final textEditingController = TextEditingController();
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
"Country/Region",
'Country/Region',
style: Theme.of(context).textTheme.bodySmall!.copyWith(
fontSize: 14,
fontWeight: FontWeight.w400,
@ -246,7 +250,8 @@ class _LoginWebPageState extends State<LoginWebPage> with HelperResponsiveLayout
searchInnerWidgetHeight: 50,
searchInnerWidget: Container(
height: 50,
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
padding:
const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
child: TextFormField(
style: const TextStyle(color: Colors.black),
controller: textEditingController,
@ -261,7 +266,8 @@ class _LoginWebPageState extends State<LoginWebPage> with HelperResponsiveLayout
),
searchMatchFn: (item, searchValue) {
// Use the item's child text (region name) for searching.
final regionName = (item.child as Text).data?.toLowerCase() ?? '';
final regionName =
(item.child as Text).data?.toLowerCase() ?? '';
final search = searchValue.toLowerCase().trim();
// Debugging print statement to ensure values are captured correctly.
// Return true if the region name contains the search term.
@ -286,7 +292,7 @@ class _LoginWebPageState extends State<LoginWebPage> with HelperResponsiveLayout
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
"Email",
'Email',
style: Theme.of(context)
.textTheme
.bodySmall!
@ -303,10 +309,9 @@ class _LoginWebPageState extends State<LoginWebPage> with HelperResponsiveLayout
decoration: textBoxDecoration()!.copyWith(
errorStyle: const TextStyle(height: 0),
hintText: 'Enter your email address',
hintStyle: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(color: ColorsManager.grayColor, fontWeight: FontWeight.w400)),
hintStyle: Theme.of(context).textTheme.bodySmall!.copyWith(
color: ColorsManager.grayColor,
fontWeight: FontWeight.w400)),
style: const TextStyle(color: Colors.black),
),
),
@ -320,7 +325,7 @@ class _LoginWebPageState extends State<LoginWebPage> with HelperResponsiveLayout
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
"Password",
'Password',
style: Theme.of(context)
.textTheme
.bodySmall!
@ -338,7 +343,7 @@ class _LoginWebPageState extends State<LoginWebPage> with HelperResponsiveLayout
controller: loginBloc.loginPasswordController,
onFieldSubmitted: (value) {
if (loginBloc.loginFormKey.currentState!.validate()) {
loginBloc.add(LoginButtonPressed(
loginBloc.add(LoginButtonPressed(
username: loginBloc.loginEmailController.text,
password: value,
));
@ -348,17 +353,18 @@ class _LoginWebPageState extends State<LoginWebPage> with HelperResponsiveLayout
},
decoration: textBoxDecoration()!.copyWith(
hintText: 'At least 8 characters',
hintStyle: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(color: ColorsManager.grayColor, fontWeight: FontWeight.w400),
hintStyle: Theme.of(context).textTheme.bodySmall!.copyWith(
color: ColorsManager.grayColor, fontWeight: FontWeight.w400),
suffixIcon: IconButton(
onPressed: () {
loginBloc.add(PasswordVisibleEvent(newValue: loginBloc.obscureText));
loginBloc.add(
PasswordVisibleEvent(newValue: loginBloc.obscureText));
},
icon: SizedBox(
child: SvgPicture.asset(
loginBloc.obscureText ? Assets.visiblePassword : Assets.invisiblePassword,
loginBloc.obscureText
? Assets.visiblePassword
: Assets.invisiblePassword,
height: 15,
width: 15,
),
@ -385,11 +391,11 @@ class _LoginWebPageState extends State<LoginWebPage> with HelperResponsiveLayout
));
},
child: Text(
"Forgot Password?",
style: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(color: Colors.black, fontSize: 14, fontWeight: FontWeight.w400),
'Forgot Password?',
style: Theme.of(context).textTheme.bodySmall!.copyWith(
color: Colors.black,
fontSize: 14,
fontWeight: FontWeight.w400),
),
),
],
@ -453,7 +459,8 @@ class _LoginWebPageState extends State<LoginWebPage> with HelperResponsiveLayout
);
}
Widget _buildSignInButton(BuildContext context, AuthBloc loginBloc, Size size) {
Widget _buildSignInButton(
BuildContext context, AuthBloc loginBloc, Size size) {
return Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
@ -467,7 +474,7 @@ class _LoginWebPageState extends State<LoginWebPage> with HelperResponsiveLayout
fontSize: 14,
color: loginBloc.checkValidate
? ColorsManager.whiteColors
: ColorsManager.whiteColors.withOpacity(0.2),
: ColorsManager.whiteColors.withValues(alpha: 0.2),
)),
onPressed: () {
if (loginBloc.loginFormKey.currentState!.validate()) {
@ -494,7 +501,8 @@ class _LoginWebPageState extends State<LoginWebPage> with HelperResponsiveLayout
SizedBox(
child: Text(
loginBloc.validate,
style: const TextStyle(fontWeight: FontWeight.w700, color: ColorsManager.red),
style: const TextStyle(
fontWeight: FontWeight.w700, color: ColorsManager.red),
),
)
],