diff --git a/lib/pages/auth/bloc/auth_bloc.dart b/lib/pages/auth/bloc/auth_bloc.dart index 0a3b0d24..5898f2dd 100644 --- a/lib/pages/auth/bloc/auth_bloc.dart +++ b/lib/pages/auth/bloc/auth_bloc.dart @@ -24,25 +24,33 @@ class AuthBloc extends Bloc { on(_passwordVisible); on(_fetchRegion); on(selectRegion); + on(checkEnable); + on(changeValidate); } - ////////////////////////////// forget password ////////////////////////////////// + ////////////////////////////// forget password ////////////////////////////////// final TextEditingController forgetEmailController = TextEditingController(); - final TextEditingController forgetPasswordController = TextEditingController(); + final TextEditingController forgetPasswordController = + TextEditingController(); final TextEditingController forgetOtp = TextEditingController(); final forgetFormKey = GlobalKey(); + late bool checkValidate = false; + Timer? _timer; int _remainingTime = 0; - List? regionList=[RegionModel(name: 'name', id: 'id')]; + List? regionList = [RegionModel(name: 'name', id: 'id')]; - Future _onStartTimer(StartTimerEvent event, Emitter emit) async { + Future _onStartTimer( + StartTimerEvent event, Emitter emit) async { if (_validateInputs(emit)) return; if (_timer != null && _timer!.isActive) { return; } _remainingTime = 1; - add(UpdateTimerEvent(remainingTime: _remainingTime, isButtonEnabled: false)); - _remainingTime = (await AuthenticationAPI.sendOtp(email: forgetEmailController.text,regionUuid: regionUuid))!; + add(UpdateTimerEvent( + remainingTime: _remainingTime, isButtonEnabled: false)); + _remainingTime = (await AuthenticationAPI.sendOtp( + email: forgetEmailController.text, regionUuid: regionUuid))!; _timer = Timer.periodic(const Duration(seconds: 1), (timer) { _remainingTime--; if (_remainingTime <= 0) { @@ -85,10 +93,6 @@ class AuthBloc extends Bloc { remainingTime: event.remainingTime)); } - - - - ///////////////////////////////////// login ///////////////////////////////////// final TextEditingController loginEmailController = TextEditingController(); final TextEditingController loginPasswordController = TextEditingController(); @@ -106,6 +110,7 @@ class AuthBloc extends Bloc { void _login(LoginButtonPressed event, Emitter emit) async { emit(AuthLoading()); + if (isChecked) { try { if (event.username.isEmpty || event.password.isEmpty) { @@ -115,14 +120,14 @@ class AuthBloc extends Bloc { } token = await AuthenticationAPI.loginWithEmail( model: LoginWithEmailModel( - email: event.username, - password: event.password, - regionUuid: event.regionUuid - ), + email: event.username, + password: event.password, + regionUuid: event.regionUuid), ); } catch (failure) { - validate='Something went wrong'; - emit(const LoginFailure(error: 'Something went wrong')); + validate = 'Invalid Credentials!'; + emit(AuthInitialState()); + // emit(const LoginFailure(error: 'Something went wrong')); return; } if (token.accessTokenIsNotEmpty) { @@ -137,9 +142,11 @@ class AuthBloc extends Bloc { loginPasswordController.clear(); emit(LoginSuccess()); } else { + emit(const LoginFailure(error: 'Something went wrong')); } } else { + emit(const LoginFailure(error: 'Accept terms and condition')); } } @@ -147,13 +154,13 @@ class AuthBloc extends Bloc { checkBoxToggle(CheckBoxEvent event, Emitter emit,) { emit(AuthLoading()); isChecked = event.newValue!; + add(CheckEnableEvent()); emit(LoginInitial()); } checkOtpCode(ChangePasswordEvent event, Emitter emit,) async { emit(LoadingForgetState()); - await AuthenticationAPI.verifyOtp( - email: forgetEmailController.text, otpCode: forgetOtp.text); + await AuthenticationAPI.verifyOtp(email: forgetEmailController.text, otpCode: forgetOtp.text); emit(SuccessForgetState()); } @@ -163,30 +170,32 @@ class AuthBloc extends Bloc { emit(PasswordVisibleState()); } - void launchURL(String url) { - - } - - + void launchURL(String url) {} /////////////////////////////////////VALIDATORS///////////////////////////////////// String? validatePassword(String? value) { if (value == null || value.isEmpty) { - return 'Password is required'; - } else if (value.length < 8) { - return 'Password must be at least 8 characters'; + return ''; } return null; } String? validateEmail(String? value) { + if (value == null || value.isEmpty) { return 'Email is required'; } else if (!RegExp(r'^[^@]+@[^@]+\.[^@]+').hasMatch(value)) { return 'Enter a valid email address'; - }else if (regionUuid=='') { + } else if (regionUuid == '') { return 'Please select your region'; } + validate=''; + return null; + } + String? loginValidateEmail(String? value) { + if (!RegExp(r'^[^@]+@[^@]+\.[^@]+').hasMatch(value!)) { + return ''; + } return null; } @@ -277,17 +286,17 @@ class AuthBloc extends Bloc { return '$maskedLocalPart@$domainPart'; } - - - - static Future getTokenAndValidate() async { + static Future 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'; @@ -312,19 +321,17 @@ class AuthBloc extends Bloc { void _fetchRegion(RegionInitialEvent event, Emitter emit) async { try { emit(AuthLoading()); - regionList = await AuthenticationAPI.fetchRegion(); + regionList = await AuthenticationAPI.fetchRegion(); emit(AuthInitialState()); } catch (e) { - emit( LoginFailure(error: e.toString())); - + emit(LoginFailure(error: e.toString())); } } - Future selectRegion(SelectRegionEvent event, Emitter emit) async { try { emit(AuthLoading()); - regionUuid= event.val; + regionUuid = event.val; emit(AuthInitialState()); } catch (e) { emit(FailureForgetState(error: e.toString())); @@ -340,7 +347,8 @@ class AuthBloc extends Bloc { final String 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 + if (days > 0 || hours > 0) + hours.toString().padLeft(2, '0'), // Show hours if there are days or hours minutes.toString().padLeft(2, '0'), seconds.toString().padLeft(2, '0'), ].join(':'); @@ -348,8 +356,19 @@ class AuthBloc extends Bloc { return formattedTime; } - + bool checkEnable( CheckEnableEvent event, Emitter emit,) { + emit(AuthLoading()); + checkValidate = isChecked==true && + loginPasswordController.text.isNotEmpty && + loginEmailController.text.isNotEmpty && + regionUuid != ''; + emit(LoginInitial()); + return checkValidate; + } + changeValidate(ChangeValidateEvent event, Emitter emit,){ + emit(AuthLoading()); + validate=''; + print('validate'); + emit(LoginInitial()); + } } - - - diff --git a/lib/pages/auth/bloc/auth_event.dart b/lib/pages/auth/bloc/auth_event.dart index 50cd5c56..4f80a2db 100644 --- a/lib/pages/auth/bloc/auth_event.dart +++ b/lib/pages/auth/bloc/auth_event.dart @@ -13,7 +13,7 @@ class LoginButtonPressed extends AuthEvent { final String password; final String regionUuid; - const LoginButtonPressed({required this.username, required this.password, required this.regionUuid}); + const LoginButtonPressed({required this.username, required this.password, required this.regionUuid, }); @override List get props => [username, password,regionUuid]; @@ -53,6 +53,8 @@ class PasswordVisibleEvent extends AuthEvent{ } class RegionInitialEvent extends AuthEvent {} +class CheckEnableEvent extends AuthEvent {} +class ChangeValidateEvent extends AuthEvent {} class SelectRegionEvent extends AuthEvent { final String val; diff --git a/lib/pages/auth/view/forget_password_web_page.dart b/lib/pages/auth/view/forget_password_web_page.dart index d87b277f..b0e17374 100644 --- a/lib/pages/auth/view/forget_password_web_page.dart +++ b/lib/pages/auth/view/forget_password_web_page.dart @@ -254,8 +254,7 @@ class ForgetPasswordWebPage extends StatelessWidget { SizedBox( child: TextFormField( validator: forgetBloc.passwordValidator, - keyboardType: - TextInputType.visiblePassword, + keyboardType: TextInputType.visiblePassword, controller: forgetBloc.forgetPasswordController, decoration: textBoxDecoration()!.copyWith( diff --git a/lib/pages/auth/view/login_mobile_page.dart b/lib/pages/auth/view/login_mobile_page.dart index 50684bab..98402f59 100644 --- a/lib/pages/auth/view/login_mobile_page.dart +++ b/lib/pages/auth/view/login_mobile_page.dart @@ -297,8 +297,7 @@ 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( regionUuid:'' , diff --git a/lib/pages/auth/view/login_page.dart b/lib/pages/auth/view/login_page.dart index 58b07299..92487fe4 100644 --- a/lib/pages/auth/view/login_page.dart +++ b/lib/pages/auth/view/login_page.dart @@ -1,7 +1,6 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; -import 'package:syncrow_web/pages/auth/view/login_mobile_page.dart'; import 'package:syncrow_web/pages/auth/view/login_web_page.dart'; import 'package:syncrow_web/utils/responsive_layout.dart'; @@ -11,7 +10,7 @@ class LoginPage extends StatelessWidget { Widget build(BuildContext context) { return const ResponsiveLayout( desktopBody: LoginWebPage(), - mobileBody:LoginMobilePage() + mobileBody:LoginWebPage() ); } } diff --git a/lib/pages/auth/view/login_web_page.dart b/lib/pages/auth/view/login_web_page.dart index bd2259fa..10ed36a6 100644 --- a/lib/pages/auth/view/login_web_page.dart +++ b/lib/pages/auth/view/login_web_page.dart @@ -48,11 +48,7 @@ class _LoginWebPageState extends State { } }, builder: (context, state) { - if (state is AuthLoading) { - return const Center(child: CircularProgressIndicator()); - } else { - return _buildLoginForm(context,state); - } + return _buildLoginForm(context,state); }, ), ), @@ -75,272 +71,327 @@ class _LoginWebPageState extends State { WidgetsBinding.instance.addPostFrameCallback((_) { _scrollToCenter(); }); - return FirstLayer( - second: Center( - child: ListView( - controller: _scrollController, - shrinkWrap: true, - children: [ - Container( - padding: EdgeInsets.all(size.width*0.02) , - margin: EdgeInsets.all(size.width*0.09), - decoration: BoxDecoration( - color: Colors.black.withOpacity(0.3), - borderRadius: const BorderRadius.all(Radius.circular(20)), - ), - child: Center( - child:Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Spacer(), - Expanded( - flex: 3, - child: SvgPicture.asset( - Assets.loginLogo, - ), - ), - const Spacer(), - Expanded( - 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))), - child: Form( - key: loginBloc.loginFormKey, - child: Padding( - padding: EdgeInsets.symmetric( - horizontal: size.width*0.02, - vertical: size.width*0.003), - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox(height: 40), - Text( - 'Login', - style:Theme.of(context).textTheme.headlineLarge), - SizedBox(height: size.height*0.03), - Column( + return Stack( + children: [ + FirstLayer( + second: Center( + child: ListView( + controller: _scrollController, + shrinkWrap: true, + children: [ + Container( + padding: EdgeInsets.all(size.width*0.02) , + margin: EdgeInsets.all(size.width*0.09), + decoration: BoxDecoration( + color: Colors.black.withOpacity(0.3), + borderRadius: const BorderRadius.all(Radius.circular(20)), + ), + child: Center( + child:Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Spacer(), + Expanded( + flex: 3, + child: SvgPicture.asset( + Assets.loginLogo, + ), + ), + const Spacer(), + Expanded( + 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))), + child: Form( + key: loginBloc.loginFormKey, + child: Padding( + padding: EdgeInsets.symmetric( + horizontal: size.width*0.02, + vertical: size.width*0.003), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Text( - "Country/Region", - style: Theme.of(context).textTheme.bodySmall, - ), - const SizedBox(height: 10,), - SizedBox( - child: DropdownButtonFormField( - validator:loginBloc.validateRegion , - icon: const Icon( - Icons.keyboard_arrow_down_outlined, + children: [ + const SizedBox(height: 40), + Text( + 'Login', + style:Theme.of(context).textTheme.headlineLarge), + SizedBox(height: size.height*0.03), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + "Country/Region", + style: Theme.of(context).textTheme.bodySmall!.copyWith(fontSize: 14,fontWeight: FontWeight.w400), ), - decoration: textBoxDecoration()!.copyWith( - hintText: null,), - hint: SizedBox( - width: size.width * 0.11, - child: const Align( - alignment: Alignment.centerLeft, + const SizedBox(height: 10,), + + SizedBox( + child: DropdownButtonFormField( + padding: EdgeInsets.zero, + value: loginBloc.regionList!.any((region) => region.id == loginBloc.regionUuid) + ? loginBloc.regionUuid + : null, + + validator: loginBloc.validateRegion, + icon: const Icon( + Icons.keyboard_arrow_down_outlined, + ), + decoration: textBoxDecoration()!.copyWith( + errorStyle: const TextStyle(height: 0), + hintText: null, + ), + hint: SizedBox( + width: size.width * 0.12, + child: Align( + alignment: Alignment.centerLeft, + child: Text( + 'Select your region/country', + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.bodySmall!.copyWith( + color: ColorsManager.grayColor, + fontWeight: FontWeight.w400), + overflow: TextOverflow.ellipsis, + ), + ), + ), + isDense: true, + style: const TextStyle(color: Colors.black), + items: loginBloc.regionList!.map((RegionModel region) { + return DropdownMenuItem( + value: region.id, + child: SizedBox( + width: size.width*0.06, + + child: Text(region.name)), + ); + }).toList(), + onChanged: (String? value) { + loginBloc.add(CheckEnableEvent()); + loginBloc.add(SelectRegionEvent(val: value!)); + }, + ), + ) + + + ], + ), + const SizedBox(height: 20.0), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text("Email", + style: Theme.of(context).textTheme.bodySmall!.copyWith(fontSize: 14,fontWeight: FontWeight.w400), + ), + const SizedBox( + height: 10, + ), + SizedBox( + child: TextFormField( + onChanged: (value) { + loginBloc.add(CheckEnableEvent()); + // print(loginBloc.checkEnable()); + }, + validator:loginBloc.loginValidateEmail , + controller:loginBloc.loginEmailController, + decoration: textBoxDecoration()!.copyWith( + errorStyle: const TextStyle(height: 0), // Hide the error text space + hintText: 'Enter your email address', + hintStyle: Theme.of(context).textTheme.bodySmall!.copyWith( + color: ColorsManager.grayColor, + fontWeight: FontWeight.w400) + ), + style: const TextStyle(color: Colors.black), + ), + ), + ], + ), + const SizedBox(height: 20.0), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text("Password", + style: Theme.of(context).textTheme.bodySmall!.copyWith(fontSize: 14,fontWeight: FontWeight.w400), + ), + const SizedBox( + height: 10, + ), + SizedBox( + child: TextFormField( + onChanged: (value) { + loginBloc.add(CheckEnableEvent()); + }, + validator:loginBloc.validatePassword, + obscureText:loginBloc.obscureText, + keyboardType: TextInputType.visiblePassword, + controller:loginBloc.loginPasswordController, + decoration: textBoxDecoration()!.copyWith( + hintText: 'At least 8 characters', + hintStyle: Theme.of(context).textTheme.bodySmall!.copyWith( + color: ColorsManager.grayColor, + fontWeight: FontWeight.w400), + suffixIcon: IconButton(onPressed: () { + loginBloc.add(PasswordVisibleEvent(newValue: loginBloc.obscureText)); + }, + icon: SizedBox( + child: SvgPicture.asset( + loginBloc.obscureText? + Assets.visiblePassword : + Assets.invisiblePassword, + height: 15, + width: 15, + ), + ), + ), + errorStyle: const TextStyle(height: 0), // Hide the error text space + ), + style: const TextStyle(color: Colors.black), + ), + ), + ], + ), + const SizedBox( + height: 20, + ), + SizedBox( + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + InkWell( + onTap: () { + Navigator.of(context).push(MaterialPageRoute(builder: (context) => const ForgetPasswordPage(),)); + }, child: Text( - 'Select your region/country', - textAlign: TextAlign.center, - style: TextStyle(fontSize: 14), - overflow: TextOverflow.ellipsis, + "Forgot Password?", + style: Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.black,fontSize: 14,fontWeight: FontWeight.w400), + ), + ), + ], + ), + ), + const SizedBox( + height: 20, + ), + Row( + children: [ + Transform.scale( + scale: 1.2, // Adjust the scale as needed + child: Checkbox( + fillColor: MaterialStateProperty.all(Colors.white), + activeColor: Colors.white, + value:loginBloc.isChecked, + checkColor: Colors.black, + shape: const CircleBorder(), + onChanged: (bool? newValue) { + loginBloc.add(CheckBoxEvent(newValue: newValue)); + }, + ), + ), + SizedBox( + width:size.width * 0.14, + child: RichText( + text: TextSpan( + text: 'Agree to ', + style: const TextStyle(color: Colors.white), + children: [ + TextSpan( + text: '(Terms of Service)', + style: const TextStyle( + color: Colors.black,), + recognizer: TapGestureRecognizer() + ..onTap = () { + loginBloc.launchURL( + 'https://example.com/terms'); + }, + ), + TextSpan( + text: ' (Legal Statement)', + style: const TextStyle(color: Colors.black), + recognizer: TapGestureRecognizer() + ..onTap = () { + loginBloc.launchURL( + 'https://example.com/legal'); + }, + ), + TextSpan( + text: ' (Privacy Statement)', + style: const TextStyle( + color: Colors.black), + recognizer: TapGestureRecognizer() + ..onTap = () { + loginBloc.launchURL( + 'https://example.com/privacy'); + }, + ), + ], ), ), ), - isDense: true, - style: const TextStyle(color: Colors.black), - items:loginBloc.regionList!.map((RegionModel region) { - return DropdownMenuItem( - value: region.id, - child: Text(region.name), - ); - }).toList(), - onChanged: (String? value) { + ], + ), + const SizedBox(height: 20.0), + Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox( + width:size.width * 0.2, + child: DefaultButton( + enabled: loginBloc.checkValidate, + child:Text('Sign in', + style: Theme.of(context).textTheme.labelLarge !.copyWith( + fontSize: 14, + color: + loginBloc.checkValidate ? + ColorsManager.whiteColors:ColorsManager.whiteColors.withOpacity(0.2), + ) + ), + onPressed: () { - loginBloc.add(SelectRegionEvent(val: value!,)); - }, - ), - ) + if(loginBloc.loginFormKey.currentState!.validate() ){ + loginBloc.add(LoginButtonPressed( + regionUuid:loginBloc.regionUuid, + username: loginBloc.loginEmailController.text, + password: loginBloc.loginPasswordController.text, + )); + }else{ + loginBloc.add(ChangeValidateEvent()); + } + + }, + ), + ), + ], + ), + const SizedBox(height: 15.0), + Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ SizedBox(child: Text(loginBloc.validate, + style: const TextStyle(fontWeight: FontWeight.w700,color: ColorsManager.red ),),)],) ], ), - const SizedBox(height: 20.0), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Text("Email", - style: Theme.of(context).textTheme.bodySmall, - ), - const SizedBox( - height: 10, - ), - SizedBox( - child: TextFormField( - validator:loginBloc.validateEmail , - controller:loginBloc.loginEmailController, - decoration: textBoxDecoration()!.copyWith(hintText: 'Enter your email'), - style: const TextStyle(color: Colors.black), - ), - ), - ], - ), - const SizedBox(height: 20.0), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Text("Password", style: Theme.of(context).textTheme.bodySmall,), - const SizedBox( - height: 10, - ), - SizedBox( - child: TextFormField( - validator:loginBloc.validatePassword, - obscureText:loginBloc.obscureText, - keyboardType: TextInputType.visiblePassword, - controller:loginBloc.loginPasswordController, - decoration: textBoxDecoration()!.copyWith( - hintText: 'At least 8 characters', - suffixIcon: IconButton(onPressed: () { - loginBloc.add(PasswordVisibleEvent(newValue: loginBloc.obscureText)); - }, - icon: SizedBox( - child: SvgPicture.asset( - loginBloc.obscureText? - Assets.visiblePassword : - Assets.invisiblePassword, - height: 15, - width: 15, - ), - ), - ) - ), - style: const TextStyle(color: Colors.black), - ), - ), - ], - ), - const SizedBox( - height: 20, - ), - SizedBox( - child: Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - InkWell( - onTap: () { - Navigator.of(context).push(MaterialPageRoute(builder: (context) => const ForgetPasswordPage(),)); - }, - child: Text( - "Forgot Password?", - style: Theme.of(context).textTheme.bodySmall, - ), - ), - ], - ), - ), - const SizedBox( - height: 20, - ), - Row( - children: [ - Transform.scale( - scale: 1.2, // Adjust the scale as needed - child: Checkbox( - fillColor: MaterialStateProperty.all(Colors.white), - activeColor: Colors.white, - value:loginBloc.isChecked, - checkColor: Colors.black, - shape: const CircleBorder(), - onChanged: (bool? newValue) { - loginBloc.add(CheckBoxEvent(newValue: newValue)); - }, - ), - ), - SizedBox( - width:size.width * 0.14, - child: RichText( - text: TextSpan( - text: 'Agree to ', - style: const TextStyle(color: Colors.white), - children: [ - TextSpan( - text: '(Terms of Service)', - style: const TextStyle( - color: Colors.black,), - recognizer: TapGestureRecognizer() - ..onTap = () { - loginBloc.launchURL( - 'https://example.com/terms'); - }, - ), - TextSpan( - text: ' (Legal Statement)', - style: const TextStyle(color: Colors.black), - recognizer: TapGestureRecognizer() - ..onTap = () { - loginBloc.launchURL( - 'https://example.com/legal'); - }, - ), - TextSpan( - text: ' (Privacy Statement)', - style: const TextStyle( - color: Colors.black), - recognizer: TapGestureRecognizer() - ..onTap = () { - loginBloc.launchURL( - 'https://example.com/privacy'); - }, - ), - ], - ), - ), - ), - ], - ), - const SizedBox(height: 20.0), - SizedBox( - width:size.width * 0.2, - child: DefaultButton( - backgroundColor: loginBloc.isChecked? - ColorsManager.btnColor:ColorsManager.grayColor, - child: const Text('Sign in'), - onPressed: () { - if (loginBloc.loginFormKey.currentState!.validate()) { - loginBloc.add(LoginButtonPressed( - regionUuid:loginBloc.regionUuid , - username: loginBloc.loginEmailController.text, - password: loginBloc.loginPasswordController.text, - ), - ); - } - }, - ), - ), - const SizedBox(height: 15.0), - Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ SizedBox(child: Text(loginBloc.validate, - style: const TextStyle(fontWeight: FontWeight.w700,color: ColorsManager.red ),),)],) - ], - ), - ), - ) - )), - const Spacer(), - ], - ),), + ), + ) + )), + const Spacer(), + ], + ),), + ), + ], ), - ], + ), ), - ), + if (state is AuthLoading) + const Center(child: CircularProgressIndicator()) + ], ); } } diff --git a/lib/pages/common/default_button.dart b/lib/pages/common/default_button.dart index 02254828..181e093a 100644 --- a/lib/pages/common/default_button.dart +++ b/lib/pages/common/default_button.dart @@ -59,7 +59,7 @@ class DefaultButton extends StatelessWidget { (Set states) { return enabled ? backgroundColor ?? ColorsManager.primaryColor - : Colors.grey; + : Colors.black.withOpacity(0.2); }), shape: MaterialStateProperty.all( RoundedRectangleBorder( diff --git a/lib/utils/style.dart b/lib/utils/style.dart index 41599fad..6a31ca8c 100644 --- a/lib/utils/style.dart +++ b/lib/utils/style.dart @@ -8,17 +8,25 @@ InputDecoration? textBoxDecoration({bool suffixIcon = false}) => InputDecoration filled: true, // Enable background filling fillColor: Colors.grey.shade200, // Set the background color border: OutlineInputBorder( - borderRadius: BorderRadius.circular(15), // Add border radius + borderRadius: BorderRadius.circular(20), // Add border radius borderSide: BorderSide.none, // Remove the underline ), enabledBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(15), // Add border radius + borderRadius: BorderRadius.circular(20), // Add border radius borderSide: BorderSide.none, // Remove the underline ), focusedBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(15), // Add border radius + borderRadius: BorderRadius.circular(20), // Add border radius borderSide: BorderSide.none, // Remove the underline ), + errorBorder: OutlineInputBorder( + borderSide: BorderSide(color: Colors.red, width: 2), + borderRadius: BorderRadius.circular(20), + ), + focusedErrorBorder: OutlineInputBorder( + borderSide: BorderSide(color: Colors.red, width: 2), + borderRadius: BorderRadius.circular(20), + ), );