From 1f5a119c6091bee1f4a8cfb5319566e88458b17f Mon Sep 17 00:00:00 2001 From: mohammad Date: Tue, 6 Aug 2024 11:21:14 +0300 Subject: [PATCH 1/5] Home page --- lib/main.dart | 5 + lib/pages/auth/bloc/auth_bloc.dart | 36 +- lib/pages/auth/bloc/auth_event.dart | 7 +- lib/pages/auth/bloc/auth_state.dart | 4 +- lib/pages/auth/model/region_model.dart | 25 + .../auth/view/forget_password_web_page.dart | 405 ++++++------- lib/pages/auth/view/login_mobile_page.dart | 87 +-- lib/pages/auth/view/login_web_page.dart | 559 +++++++----------- lib/services/api/http_interceptor.dart | 1 + lib/services/auth_api.dart | 56 +- lib/utils/constants/api_const.dart | 1 + 11 files changed, 521 insertions(+), 665 deletions(-) create mode 100644 lib/pages/auth/model/region_model.dart diff --git a/lib/main.dart b/lib/main.dart index 379442f2..6a3f450f 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -33,6 +33,11 @@ class MyApp extends StatelessWidget { }, ), theme: ThemeData( + textTheme: const TextTheme( + bodySmall:TextStyle(), + bodyLarge:TextStyle(), + bodyMedium:TextStyle(), + ), colorScheme: ColorScheme.fromSeed( seedColor: Colors.deepPurple), // Set up color scheme useMaterial3: true, // Enable Material 3 diff --git a/lib/pages/auth/bloc/auth_bloc.dart b/lib/pages/auth/bloc/auth_bloc.dart index c1e21c71..e7b752f8 100644 --- a/lib/pages/auth/bloc/auth_bloc.dart +++ b/lib/pages/auth/bloc/auth_bloc.dart @@ -1,11 +1,11 @@ import 'dart:async'; -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:syncrow_web/pages/auth/bloc/auth_event.dart'; import 'package:syncrow_web/pages/auth/bloc/auth_state.dart'; import 'package:syncrow_web/pages/auth/model/login_with_email_model.dart'; +import 'package:syncrow_web/pages/auth/model/region_model.dart'; import 'package:syncrow_web/pages/auth/model/token.dart'; import 'package:syncrow_web/pages/auth/model/user_model.dart'; import 'package:syncrow_web/services/auth_api.dart'; @@ -22,35 +22,32 @@ class AuthBloc extends Bloc { on(_onStopTimer); on(_onUpdateTimer); on(_passwordVisible); + on(_fetchRegion); } -////////////////////////////// forget password ////////////////////////////////// + ////////////////////////////// forget password ////////////////////////////////// final TextEditingController forgetEmailController = TextEditingController(); final TextEditingController forgetPasswordController = TextEditingController(); final TextEditingController forgetOtp = TextEditingController(); final forgetFormKey = GlobalKey(); Timer? _timer; int _remainingTime = 0; + List? regionList; Future _onStartTimer(StartTimerEvent event, Emitter emit) async { if (_validateInputs(emit)) return; - print("StartTimerEvent received"); if (_timer != null && _timer!.isActive) { - print("Timer is already active"); return; } _remainingTime = 60; add(UpdateTimerEvent( remainingTime: _remainingTime, isButtonEnabled: false)); - print("Timer started, initial remaining time: $_remainingTime"); await AuthenticationAPI.sendOtp(email: forgetEmailController.text); _timer = Timer.periodic(const Duration(seconds: 1), (timer) { _remainingTime--; - print("Timer tick, remaining time: $_remainingTime"); // Debug print if (_remainingTime <= 0) { _timer?.cancel(); add(const UpdateTimerEvent(remainingTime: 0, isButtonEnabled: true)); - print("Timer finished"); // Debug print } else { add(UpdateTimerEvent( remainingTime: _remainingTime, isButtonEnabled: false)); @@ -92,8 +89,6 @@ class AuthBloc extends Bloc { - - ///////////////////////////////////// login ///////////////////////////////////// final TextEditingController loginEmailController = TextEditingController(); final TextEditingController loginPasswordController = TextEditingController(); @@ -108,7 +103,7 @@ class AuthBloc extends Bloc { bool showValidationMessage = false; void _login(LoginButtonPressed event, Emitter emit) async { - emit(LoginLoading()); + emit(AuthLoading()); if (isChecked) { try { if (event.username.isEmpty || event.password.isEmpty) { @@ -128,7 +123,6 @@ class AuthBloc extends Bloc { return; } if (token.accessTokenIsNotEmpty) { - debugPrint('token: ${token.accessToken}'); FlutterSecureStorage storage = const FlutterSecureStorage(); await storage.write( key: Token.loginAccessTokenKey, value: token.accessToken); @@ -148,7 +142,7 @@ class AuthBloc extends Bloc { } checkBoxToggle(CheckBoxEvent event, Emitter emit,) { - emit(LoginLoading()); + emit(AuthLoading()); isChecked = event.newValue!; emit(LoginInitial()); } @@ -161,15 +155,13 @@ class AuthBloc extends Bloc { } void _passwordVisible(PasswordVisibleEvent event, Emitter emit) { - emit(LoginLoading()); + emit(AuthLoading()); obscureText = !event.newValue!; emit(PasswordVisibleState()); } void launchURL(String url) { - if (kDebugMode) { - print('Launching URL: $url'); - } + } @@ -320,6 +312,18 @@ class AuthBloc extends Bloc { } } + void _fetchRegion(RegionInitialEvent event, Emitter emit) async { + try { + emit(AuthLoading()); + regionList = await AuthenticationAPI.fetchRegion(); + emit(LoginSuccess()); + } catch (e) { + emit( LoginFailure(error: e.toString())); + + } + } + + } diff --git a/lib/pages/auth/bloc/auth_event.dart b/lib/pages/auth/bloc/auth_event.dart index cdcfc51e..8a410555 100644 --- a/lib/pages/auth/bloc/auth_event.dart +++ b/lib/pages/auth/bloc/auth_event.dart @@ -17,7 +17,6 @@ class LoginButtonPressed extends AuthEvent { List get props => [username, password]; } - class CheckBoxEvent extends AuthEvent { final bool? newValue; @@ -49,4 +48,8 @@ class PasswordVisibleEvent extends AuthEvent{ final bool? newValue; const PasswordVisibleEvent({required this.newValue,}); -} \ No newline at end of file +} + +class RegionInitialEvent extends AuthEvent {} + +class SelectRegionEvent extends AuthEvent {} diff --git a/lib/pages/auth/bloc/auth_state.dart b/lib/pages/auth/bloc/auth_state.dart index 4620c722..9814955a 100644 --- a/lib/pages/auth/bloc/auth_state.dart +++ b/lib/pages/auth/bloc/auth_state.dart @@ -11,7 +11,7 @@ class LoginInitial extends AuthState {} class AuthTokenLoading extends AuthState {} -class LoginLoading extends AuthState {} +class AuthLoading extends AuthState {} class LoginSuccess extends AuthState {} @@ -74,5 +74,3 @@ class AuthSuccess extends AuthState {} class AuthTokenSuccess extends AuthSuccess {} - -// class AuthState extends AuthState {} diff --git a/lib/pages/auth/model/region_model.dart b/lib/pages/auth/model/region_model.dart new file mode 100644 index 00000000..fd6306a2 --- /dev/null +++ b/lib/pages/auth/model/region_model.dart @@ -0,0 +1,25 @@ + + +class RegionModel { + final String name; + final String id; + + RegionModel({ + required this.name, + required this.id, + }); + + factory RegionModel.fromJson(Map json) { + return RegionModel( + name: json['regionName'], + id: json['uuid'].toString(), // Ensure id is a String + ); + } + + Map toJson() { + return { + 'regionName': name, + 'uuid': id, + }; + } +} diff --git a/lib/pages/auth/view/forget_password_web_page.dart b/lib/pages/auth/view/forget_password_web_page.dart index 87ca4dee..2ed8bb4b 100644 --- a/lib/pages/auth/view/forget_password_web_page.dart +++ b/lib/pages/auth/view/forget_password_web_page.dart @@ -19,9 +19,7 @@ class ForgetPasswordWebPage extends StatelessWidget { create: (context) => AuthBloc(), child: BlocConsumer( listener: (context, state) { - if (state is LoadingForgetState) { - - } else if (state is SuccessForgetState){ + if (state is SuccessForgetState){ Navigator.of(context).pop(); } else if (state is FailureForgetState) { @@ -47,232 +45,237 @@ class ForgetPasswordWebPage extends StatelessWidget { Widget _buildForm(BuildContext context, AuthState state) { final forgetBloc = BlocProvider.of(context); return FirstLayer( - second: Container( - padding:const EdgeInsets.all(50) , - margin: const EdgeInsets.all(50), - decoration: BoxDecoration( - color: Colors.black.withOpacity(0.3), - borderRadius: const BorderRadius.all(Radius.circular(20)), - ), - child: Center( - child: ListView( - shrinkWrap: true, - children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Spacer(), - Expanded( - flex: 2, - child: SvgPicture.asset( - Assets.loginLogo, + second: Center( + child: ListView( + children: [ + Container( + padding:const EdgeInsets.all(50) , + margin: const EdgeInsets.all(90), + 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(), - 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: forgetBloc.forgetFormKey, - child: Padding( - - padding: const EdgeInsets.symmetric(horizontal: 40, vertical: 25), - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox(height: 10), - const Text( - 'Forget Password', - style: TextStyle( - color: Colors.white, - fontSize: 24, - fontWeight: FontWeight.bold), - ), - const SizedBox(height: 20), - Text( - 'Please fill in your account information to\n retrieve your password', - style: smallTextStyle, - ), - const SizedBox(height: 20), - Column( + 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: forgetBloc.forgetFormKey, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 40, vertical: 25), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ + children: [ + const SizedBox(height: 10), + const Text( + 'Forget Password', + style: TextStyle( + color: Colors.white, + fontSize: 24, + fontWeight: FontWeight.bold), + ), + const SizedBox(height: 20), Text( - "Country/Region", + 'Please fill in your account information to\nretrieve your password', style: smallTextStyle, ), - const SizedBox(height: 10), - SizedBox( - width: MediaQuery.of(context).size.width * 0.2, - child: DropdownButtonFormField( - validator: forgetBloc.validateRegion, - icon: const Icon( - Icons.keyboard_arrow_down_outlined, + const SizedBox(height: 20), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + "Country/Region", + style: smallTextStyle, ), - decoration: textBoxDecoration()!.copyWith( - hintText: null, + const SizedBox(height: 10), + SizedBox( + child: DropdownButtonFormField( + validator: forgetBloc.validateRegion, + icon: const Icon( + Icons.keyboard_arrow_down_outlined, + ), + decoration: textBoxDecoration()!.copyWith( + hintText: null, + ), + hint: SizedBox( + width: MediaQuery.sizeOf(context).width * 0.11, + child: const Align( + alignment: Alignment.centerLeft, + child: Text( + 'Select your region/country', + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + + ), + ), + ), + isDense: true, + style: const TextStyle(color: Colors.black), + items: forgetBloc.regions.map((String region) { + return DropdownMenuItem( + value: region, + child: Text(region), + ); + }).toList(), + onChanged: (String? value) { + print(value); + }, + ), + ) + ], + ), + const SizedBox(height: 20), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text("Account", + style: smallTextStyle, ), - hint: const Align( - alignment: Alignment.centerLeft, - child: Text( - 'Select your region/country', - textAlign: TextAlign.center, + const SizedBox(height: 10), + SizedBox( + child: TextFormField( + validator: forgetBloc.validateEmail, + controller: forgetBloc.forgetEmailController, + decoration: textBoxDecoration()!.copyWith(hintText: 'Enter your email'), + style: const TextStyle(color: Colors.black), ), ), - isDense: true, - style: const TextStyle(color: Colors.black), - items: forgetBloc.regions.map((String region) { - return DropdownMenuItem( - value: region, - child: Text(region), - ); - }).toList(), - onChanged: (String? value) { - print(value); - }, - ), - ) - ], - ), - const SizedBox(height: 20), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Text("Account", - style: smallTextStyle,), - const SizedBox(height: 10), - SizedBox( - width: MediaQuery.sizeOf(context).width * 0.2, - child: TextFormField( - validator: forgetBloc.validateEmail, - controller: forgetBloc.forgetEmailController, - 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("One Time Password", - style: smallTextStyle,), - const SizedBox(height: 10), - SizedBox( - width: MediaQuery.sizeOf(context).width * 0.2, - child: TextFormField( - validator: forgetBloc.validateCode, - keyboardType: TextInputType.visiblePassword, - controller: forgetBloc.forgetOtp, - decoration: textBoxDecoration()!.copyWith( - hintText: 'Enter Code', - suffixIcon: SizedBox( - width: 100, - child: Center( - child: InkWell( - onTap: () { - BlocProvider.of(context).add(StartTimerEvent()); - }, - child: Text( - 'Get Code ${state is TimerState && !state.isButtonEnabled ? "(${state.remainingTime.toString()})" : ""}', - style: TextStyle( - color: state is TimerState && !state.isButtonEnabled - ? Colors.grey - : ColorsManager.btnColor, + const SizedBox(height: 20.0), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text("One Time Password", + style: smallTextStyle,), + const SizedBox(height: 10), + SizedBox( + child: TextFormField( + validator: forgetBloc.validateCode, + keyboardType: TextInputType.visiblePassword, + controller: forgetBloc.forgetOtp, + decoration: textBoxDecoration()!.copyWith( + hintText: 'Enter Code', + suffixIcon: SizedBox( + width: 100, + child: Center( + child: InkWell( + onTap: () { + BlocProvider.of(context).add(StartTimerEvent()); + }, + child: Text( + 'Get Code ${state is TimerState && !state.isButtonEnabled ? "(${state.remainingTime.toString()})" : ""}', + style: TextStyle( + color: state is TimerState && !state.isButtonEnabled + ? Colors.grey + : ColorsManager.btnColor, + ), + ), ), ), ), ), + style: const TextStyle(color: Colors.black), ), ), - style: const TextStyle(color: Colors.black), - ), + ], ), - ], - ), - const SizedBox(height: 20.0), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Text("Password", - style: smallTextStyle,), - const SizedBox(height: 10), + const SizedBox(height: 20.0), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text("Password", + style: smallTextStyle,), + const SizedBox(height: 10), + SizedBox( + child: TextFormField( + validator: forgetBloc.passwordValidator, + keyboardType: TextInputType.visiblePassword, + controller: forgetBloc.forgetPasswordController, + decoration: textBoxDecoration()!.copyWith( + hintText: 'At least 8 characters', + ), + style: const TextStyle(color: Colors.black), + ), + ), + ], + ), + const SizedBox( + height: 10, + ), + const SizedBox(height: 20.0), SizedBox( width: MediaQuery.sizeOf(context).width * 0.2, - child: TextFormField( - validator: forgetBloc.passwordValidator, - keyboardType: TextInputType.visiblePassword, - controller: forgetBloc.forgetPasswordController, - decoration: textBoxDecoration()!.copyWith( - hintText: 'At least 8 characters', - ), - style: const TextStyle(color: Colors.black), + child: DefaultButton( + backgroundColor: ColorsManager.btnColor, + child: const Text('Submit'), + onPressed: () { + if (forgetBloc.forgetFormKey.currentState!.validate()) { + forgetBloc.add(ChangePasswordEvent()); + } + }, ), ), + SizedBox(height: 10,), + SizedBox( + width: MediaQuery.sizeOf(context).width * 0.2, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const Flexible( + child: Text( + "Do you have an account? ", + style: TextStyle(color: Colors.white), + )), + InkWell( + onTap: () { + Navigator.pop(context); + }, + child: const Flexible( + child: Text( + "Sign in", + )), + ), + ], + ), + ) ], ), - const SizedBox( - height: 10, - ), - const SizedBox(height: 20.0), - SizedBox( - width: MediaQuery.sizeOf(context).width * 0.2, - child: DefaultButton( - backgroundColor: ColorsManager.btnColor, - child: const Text('Submit'), - onPressed: () { - if (forgetBloc.forgetFormKey.currentState!.validate()) { - forgetBloc.add(ChangePasswordEvent()); - } - }, - ), - ), - SizedBox(height: 10,), - SizedBox( - width: MediaQuery.sizeOf(context).width * 0.2, - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - const Flexible( - child: Text( - "Do you have an account? ", - style: TextStyle(color: Colors.white), - )), - InkWell( - onTap: () { - Navigator.pop(context); - }, - child: const Flexible( - child: Text( - "Sign in", - )), - ), - ], - ), - ) - ], + ), ), ), ), - ), - const Spacer(), - ], + const Spacer(), + ], + ), ), - ], - ), + ), + ], ), - ), + ) ); } } diff --git a/lib/pages/auth/view/login_mobile_page.dart b/lib/pages/auth/view/login_mobile_page.dart index 7b52400a..3e709735 100644 --- a/lib/pages/auth/view/login_mobile_page.dart +++ b/lib/pages/auth/view/login_mobile_page.dart @@ -15,7 +15,6 @@ import 'package:syncrow_web/utils/style.dart'; class LoginMobilePage extends StatelessWidget { const LoginMobilePage({super.key}); - @override Widget build(BuildContext context) { return Scaffold( @@ -39,7 +38,7 @@ class LoginMobilePage extends StatelessWidget { } }, builder: (context, state) { - if (state is LoginLoading) { + if (state is AuthLoading) { return const Center(child: CircularProgressIndicator()); } else { return _buildLoginForm(context); @@ -311,90 +310,6 @@ class LoginMobilePage extends StatelessWidget { }, ), ), - // Padding( - // padding: const EdgeInsets.all(5.0), - // child: SizedBox( - // width: MediaQuery.sizeOf(context).width * 0.2, - // child: Row( - // mainAxisAlignment: MainAxisAlignment.center, - // crossAxisAlignment: CrossAxisAlignment.center, - // children: [ - // Expanded(child: Image.asset(Assets.liftLine)), - // Expanded( - // child: Padding( - // padding: const EdgeInsets.all(5.0), - // child: Text('Or sign in with', - // style: smallTextStyle.copyWith(fontSize: 10), - // ), - // ) - // ), - // Expanded(child: Image.asset(Assets.rightLine)), - // ], - // ), - // ), - // ), - // SizedBox( - // width: MediaQuery.sizeOf(context).width * 0.2, - // child: Row( - // crossAxisAlignment: CrossAxisAlignment.center, - // children: [ - // Expanded( - // child: Container( - // decoration: containerDecoration, - // child:InkWell( - // child: Padding( - // padding: const EdgeInsets.all(8.0), - // child: Row( - // mainAxisAlignment: MainAxisAlignment.spaceAround, - // crossAxisAlignment: CrossAxisAlignment.center, - // children: [ - // SvgPicture.asset( - // Assets.google, - // fit: BoxFit.cover, - // ), - // const Flexible( - // child: Text('Google', - // style: TextStyle(color: Colors.black), - // ), - // ), - // ], - // ), - // ), - // onTap: () {}, - // ), - // ), - // ), - // SizedBox(width: 10,), - // Expanded( - // child: Container( - // decoration: containerDecoration, - // child:InkWell( - // child: Padding( - // padding: const EdgeInsets.all(8.0), - // child: Row( - // mainAxisAlignment: MainAxisAlignment.spaceAround, - // crossAxisAlignment: CrossAxisAlignment.center, - // children: [ - // SvgPicture.asset( - // Assets.facebook, - // fit: BoxFit.cover, - // ), - // const Flexible( - // child: Text('Facebook', - // style: TextStyle(color: Colors.black), - // ), - // ), - // ], - // ), - // ), - // onTap: () {}, - // ), - // ), - // ), - // - // ], - // ), - // ), const SizedBox( child: Row( mainAxisAlignment: MainAxisAlignment.center, diff --git a/lib/pages/auth/view/login_web_page.dart b/lib/pages/auth/view/login_web_page.dart index 67f7c7bc..ecacfb09 100644 --- a/lib/pages/auth/view/login_web_page.dart +++ b/lib/pages/auth/view/login_web_page.dart @@ -22,7 +22,7 @@ class LoginWebPage extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( body: BlocProvider( - create: (context) => AuthBloc(), + create: (BuildContext context) => AuthBloc()..add(RegionInitialEvent()), child: BlocConsumer( listener: (context, state) { if (state is LoginSuccess) { @@ -41,7 +41,7 @@ class LoginWebPage extends StatelessWidget { } }, builder: (context, state) { - if (state is LoginLoading) { + if (state is AuthLoading) { return const Center(child: CircularProgressIndicator()); } else { return _buildLoginForm(context,state); @@ -55,364 +55,265 @@ class LoginWebPage extends StatelessWidget { Widget _buildLoginForm(BuildContext context,AuthState state) { final loginBloc = BlocProvider.of(context); return FirstLayer( - second: Container( - margin: const EdgeInsets.all(50), - decoration: BoxDecoration( - color: Colors.black.withOpacity(0.3), - borderRadius: const BorderRadius.all(Radius.circular(20)), - ), - child: Center( - child: ListView( - shrinkWrap: true, - children: [ - Row( + second: Center( + child: ListView( + shrinkWrap: true, + children: [ + Container( + padding:const EdgeInsets.all(50) , + margin: const EdgeInsets.all(90), + 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: 2, + flex: 3, child: SvgPicture.asset( Assets.loginLogo, ), ), const Spacer(), - 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: const EdgeInsets.symmetric(horizontal: 50, vertical: 25), - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox(height: 15), - const Text( - 'Login', - style: TextStyle( - color: Colors.white, - fontSize: 24, - fontWeight: FontWeight.bold), - ), - const SizedBox(height: 40), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Text( - "Country/Region", - style: smallTextStyle, - ), - const SizedBox( - height: 10, - ), - SizedBox( - width: MediaQuery.of(context).size.width * 0.2, - child: DropdownButtonFormField( - validator:loginBloc.validateRegion , - icon: const Icon( - Icons.keyboard_arrow_down_outlined, + 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: const EdgeInsets.symmetric(horizontal: 50, vertical: 25), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 15), + const Text( + 'Login', + style: TextStyle( + color: Colors.white, + fontSize: 24, + fontWeight: FontWeight.bold), + ), + const SizedBox(height: 40), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + "Country/Region", + style: smallTextStyle, + ), + const SizedBox(height: 10,), + SizedBox( + child: DropdownButtonFormField( + validator:loginBloc.validateRegion , + icon: const Icon( + Icons.keyboard_arrow_down_outlined, + ), + decoration: textBoxDecoration()!.copyWith( + hintText: null,), + hint: SizedBox( + width: MediaQuery.sizeOf(context).width * 0.11, + child: const Align( + alignment: Alignment.centerLeft, + child: Text( + 'Select your region/country', + textAlign: TextAlign.center, + style: TextStyle(fontSize: 14), + overflow: TextOverflow.ellipsis, + ), + ), + ), + isDense: true, + style: const TextStyle(color: Colors.black), + items:loginBloc.regions.map((String region) { + return DropdownMenuItem( + value: region, + child: Text(region), + ); + }).toList(), + onChanged: (String? value) { + print(value); + }, + ), + ) + ], + ), + const SizedBox(height: 20.0), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text("Email", + style: smallTextStyle, + ), + 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: smallTextStyle,), + const SizedBox( + height: 10, ), - decoration: textBoxDecoration()!.copyWith( - hintText: null, - ), - hint: const Align( - alignment: Alignment.centerLeft, - child: Text( - 'Select your region/country', - textAlign: TextAlign.center, + 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), ), ), - isDense: true, - style: const TextStyle(color: Colors.black), - items:loginBloc.regions.map((String region) { - return DropdownMenuItem( - value: region, - child: Text(region), - ); - }).toList(), - onChanged: (String? value) { - print(value); - }, - ), - ) - ], - ), - const SizedBox(height: 20.0), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Text("Email", - style: smallTextStyle, + ], ), const SizedBox( - height: 10, + height: 20, ), SizedBox( - width: MediaQuery.sizeOf(context).width * 0.2, - 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: smallTextStyle,), - const SizedBox( - height: 10, - ), - SizedBox( - width: MediaQuery.sizeOf(context).width * 0.2, - 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, + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + InkWell( + onTap: () { + Navigator.of(context).push(MaterialPageRoute(builder: (context) => const ForgetPasswordPage(),)); + }, + child: Text( + "Forgot Password?", + style: smallTextStyle, ), ), - ) - ), - style: const TextStyle(color: Colors.black), + ], ), ), - ], - ), - const SizedBox( - height: 20, - ), - SizedBox( - width: MediaQuery.of(context).size.width * 0.2, - child: Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - InkWell( - onTap: () { - Navigator.of(context).push(MaterialPageRoute(builder: (context) => const ForgetPasswordPage(),)); - }, - child: Text( - "Forgot Password?", - style: smallTextStyle, - ), - ), - ], - ), - ), - const SizedBox( - height: 32, - ), - 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)); - }, - ), + const SizedBox( + height: 32, ), + 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: MediaQuery.sizeOf(context).width * 0.16, + 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: 30.0), SizedBox( width: MediaQuery.sizeOf(context).width * 0.2, - 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'); - }, + child: DefaultButton( + backgroundColor: loginBloc.isChecked? + ColorsManager.btnColor:ColorsManager.grayColor, + child: const Text('Sign in'), + onPressed: () { + if (loginBloc.loginFormKey.currentState!.validate()) { + loginBloc.add(LoginButtonPressed( + username: loginBloc.loginEmailController.text, + password: loginBloc.loginPasswordController.text, ), - 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: 30.0), - SizedBox( - width: MediaQuery.sizeOf(context).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( - username: loginBloc.loginEmailController.text, - password: loginBloc.loginPasswordController.text, - ), - ); - } - }, - ), - ), - ], - ), - ), - ) - ), + ], + ), + ), + ) + )), const Spacer(), ], - ), - ], - )), + ),), + ) + ], + ), ), ); } } -// Padding( -// padding: const EdgeInsets.all(5.0), -// child: SizedBox( -// width: MediaQuery.sizeOf(context).width * 0.2, -// child: Row( -// mainAxisAlignment: MainAxisAlignment.center, -// crossAxisAlignment: CrossAxisAlignment.center, -// children: [ -// Expanded(child: Image.asset(Assets.liftLine)), -// Expanded( -// child: Padding( -// padding: const EdgeInsets.all(5.0), -// child: Text('Or sign in with', -// style: smallTextStyle.copyWith(fontSize: 10), -// ), -// ) -// ), -// Expanded(child: Image.asset(Assets.rightLine)), -// ], -// ), -// ), -// ), -// SizedBox( -// width: MediaQuery.sizeOf(context).width * 0.2, -// child: Row( -// crossAxisAlignment: CrossAxisAlignment.center, -// children: [ -// Expanded( -// child: Container( -// decoration: containerDecoration, -// child:InkWell( -// child: Padding( -// padding: const EdgeInsets.all(8.0), -// child: Row( -// mainAxisAlignment: MainAxisAlignment.spaceAround, -// crossAxisAlignment: CrossAxisAlignment.center, -// children: [ -// SvgPicture.asset( -// Assets.google, -// fit: BoxFit.cover, -// ), -// const Flexible( -// child: Text('Google', -// style: TextStyle(color: Colors.black), -// ), -// ), -// ], -// ), -// ), -// onTap: () {}, -// ), -// ), -// ), -// SizedBox(width: 10,), -// Expanded( -// child: Container( -// decoration: containerDecoration, -// child:InkWell( -// child: Padding( -// padding: const EdgeInsets.all(8.0), -// child: Row( -// mainAxisAlignment: MainAxisAlignment.spaceAround, -// crossAxisAlignment: CrossAxisAlignment.center, -// children: [ -// SvgPicture.asset( -// Assets.facebook, -// fit: BoxFit.cover, -// ), -// const Flexible( -// child: Text('Facebook', -// style: TextStyle(color: Colors.black), -// ), -// ), -// ], -// ), -// ), -// onTap: () {}, -// ), -// ), -// ), -// -// ], -// ), -// ), -// SizedBox( -// width: MediaQuery.sizeOf(context).width * 0.2, -// child: const Row( -// mainAxisAlignment: MainAxisAlignment.center, -// crossAxisAlignment: CrossAxisAlignment.center, -// children: [ -// Flexible( -// child: Text( -// "Don't you have an account? ", -// style: TextStyle(color: Colors.white), -// )), -// Flexible( -// child: Text( -// "Sign up", -// )), -// ], -// ), -// ) \ No newline at end of file diff --git a/lib/services/api/http_interceptor.dart b/lib/services/api/http_interceptor.dart index 66e6302a..ff3fc0d4 100644 --- a/lib/services/api/http_interceptor.dart +++ b/lib/services/api/http_interceptor.dart @@ -13,6 +13,7 @@ class HTTPInterceptor extends InterceptorsWrapper { List headerExclusionListOfAddedParameters = [ ApiEndpoints.login, + ApiEndpoints.getRegion ]; @override diff --git a/lib/services/auth_api.dart b/lib/services/auth_api.dart index 3fc84c81..58a705ff 100644 --- a/lib/services/auth_api.dart +++ b/lib/services/auth_api.dart @@ -1,5 +1,6 @@ import 'dart:convert'; +import 'package:syncrow_web/pages/auth/model/region_model.dart'; import 'package:syncrow_web/pages/auth/model/token.dart'; import 'package:syncrow_web/services/api/http_service.dart'; import 'package:syncrow_web/utils/constants/api_const.dart'; @@ -17,51 +18,50 @@ class AuthenticationAPI { return response; } - static Future forgetPassword({ required var email, required var password}) async { + static Future forgetPassword( + {required var email, required var password}) async { final response = await HTTPService().post( path: ApiEndpoints.forgetPassword, - body: { - "email": email, - "password": password - }, + body: {"email": email, "password": password}, showServerMessage: true, - expectedResponseModel: (json) { - }); + expectedResponseModel: (json) {}); return response; } - static Future sendOtp({ required var email}) async { + static Future sendOtp({required var email}) async { final response = await HTTPService().post( path: ApiEndpoints.sendOtp, - body: { - "email": email, - "type": "VERIFICATION" - }, + body: {"email": email, "type": "VERIFICATION"}, showServerMessage: true, - expectedResponseModel: (json) { - print('json===$json'); - }); - + expectedResponseModel: (json) {}); return response; } - static Future verifyOtp({ required String email, required String otpCode}) async { + static Future verifyOtp( + {required String email, required String otpCode}) async { final response = await HTTPService().post( path: ApiEndpoints.verifyOtp, - body: { - "email": email, - "type": "VERIFICATION", - "otpCode": otpCode - }, + body: {"email": email, "type": "VERIFICATION", "otpCode": otpCode}, showServerMessage: true, expectedResponseModel: (json) { - print('json===${json['message']}'); - if(json['message']=='Otp Verified Successfully'){ - return true; - }else{ - return false; - } + if (json['message'] == 'Otp Verified Successfully') { + return true; + } else { + return false; + } }); return response; } + + static Future> fetchRegion() async { + final response = await HTTPService().get( + path: ApiEndpoints.getRegion, + showServerMessage: true, + expectedResponseModel: (json) { + return (json as List).map((zone) => RegionModel.fromJson(zone)).toList(); + } + ); + return response as List; + } + } diff --git a/lib/utils/constants/api_const.dart b/lib/utils/constants/api_const.dart index 93803c16..855d74e5 100644 --- a/lib/utils/constants/api_const.dart +++ b/lib/utils/constants/api_const.dart @@ -8,4 +8,5 @@ abstract class ApiEndpoints { static const String forgetPassword = '$baseUrl/authentication/user/forget-password'; static const String sendOtp = '$baseUrl/authentication/user/send-otp'; static const String verifyOtp = '$baseUrl/authentication/user/verify-otp'; + static const String getRegion = '$baseUrl/region'; } From e88be3cf17d24191d8df96f23426e893af9a9780 Mon Sep 17 00:00:00 2001 From: mohammad Date: Tue, 6 Aug 2024 16:40:03 +0300 Subject: [PATCH 2/5] auth changes --- lib/pages/auth/bloc/auth_bloc.dart | 2 + .../auth/view/forget_password_web_page.dart | 37 ++++++++++++------- lib/pages/auth/view/login_page.dart | 1 - lib/pages/auth/view/login_web_page.dart | 34 ++++++++++------- 4 files changed, 46 insertions(+), 28 deletions(-) diff --git a/lib/pages/auth/bloc/auth_bloc.dart b/lib/pages/auth/bloc/auth_bloc.dart index e7b752f8..00f6227f 100644 --- a/lib/pages/auth/bloc/auth_bloc.dart +++ b/lib/pages/auth/bloc/auth_bloc.dart @@ -98,6 +98,7 @@ class AuthBloc extends Bloc { String newPassword = ''; String maskedEmail = ''; String otpCode = ''; + String validate = ''; static Token token = Token.emptyConstructor(); static UserModel? user; bool showValidationMessage = false; @@ -118,6 +119,7 @@ class AuthBloc extends Bloc { ), ); } catch (failure) { + validate='Something went wrong'; emit(const LoginFailure(error: 'Something went wrong')); // emit(LoginFailure(error: failure.toString())); return; diff --git a/lib/pages/auth/view/forget_password_web_page.dart b/lib/pages/auth/view/forget_password_web_page.dart index 2ed8bb4b..7b1e6c93 100644 --- a/lib/pages/auth/view/forget_password_web_page.dart +++ b/lib/pages/auth/view/forget_password_web_page.dart @@ -49,7 +49,7 @@ class ForgetPasswordWebPage extends StatelessWidget { child: ListView( children: [ Container( - padding:const EdgeInsets.all(50) , + padding:const EdgeInsets.all(30) , margin: const EdgeInsets.all(90), decoration: BoxDecoration( color: Colors.black.withOpacity(0.3), @@ -92,12 +92,12 @@ class ForgetPasswordWebPage extends StatelessWidget { fontSize: 24, fontWeight: FontWeight.bold), ), - const SizedBox(height: 20), + const SizedBox(height: 10), Text( 'Please fill in your account information to\nretrieve your password', style: smallTextStyle, ), - const SizedBox(height: 20), + const SizedBox(height: 10), Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, @@ -226,18 +226,27 @@ class ForgetPasswordWebPage extends StatelessWidget { height: 10, ), const SizedBox(height: 20.0), - SizedBox( - width: MediaQuery.sizeOf(context).width * 0.2, - child: DefaultButton( - backgroundColor: ColorsManager.btnColor, - child: const Text('Submit'), - onPressed: () { - if (forgetBloc.forgetFormKey.currentState!.validate()) { - forgetBloc.add(ChangePasswordEvent()); - } - }, - ), + Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox( + width: MediaQuery.sizeOf(context).width * 0.2, + child: DefaultButton( + backgroundColor: ColorsManager.btnColor, + child: const Text('Submit'), + onPressed: () { + if (forgetBloc.forgetFormKey.currentState!.validate()) { + forgetBloc.add(ChangePasswordEvent()); + } + }, + ), + ), + ], ), + const SizedBox(height: 10.0), + SizedBox(child: Text(forgetBloc.validate, + style: const TextStyle(fontWeight: FontWeight.w700,color: ColorsManager.red ),),), SizedBox(height: 10,), SizedBox( width: MediaQuery.sizeOf(context).width * 0.2, diff --git a/lib/pages/auth/view/login_page.dart b/lib/pages/auth/view/login_page.dart index d5644b5e..58b07299 100644 --- a/lib/pages/auth/view/login_page.dart +++ b/lib/pages/auth/view/login_page.dart @@ -7,7 +7,6 @@ import 'package:syncrow_web/utils/responsive_layout.dart'; class LoginPage extends StatelessWidget { const LoginPage({super.key}); - @override Widget build(BuildContext context) { return const ResponsiveLayout( diff --git a/lib/pages/auth/view/login_web_page.dart b/lib/pages/auth/view/login_web_page.dart index ecacfb09..9b073edf 100644 --- a/lib/pages/auth/view/login_web_page.dart +++ b/lib/pages/auth/view/login_web_page.dart @@ -22,7 +22,7 @@ class LoginWebPage extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( body: BlocProvider( - create: (BuildContext context) => AuthBloc()..add(RegionInitialEvent()), + create: (BuildContext context) => AuthBloc(), child: BlocConsumer( listener: (context, state) { if (state is LoginSuccess) { @@ -54,14 +54,15 @@ class LoginWebPage extends StatelessWidget { Widget _buildLoginForm(BuildContext context,AuthState state) { final loginBloc = BlocProvider.of(context); + Size size= MediaQuery.of(context).size; return FirstLayer( second: Center( child: ListView( shrinkWrap: true, children: [ Container( - padding:const EdgeInsets.all(50) , - margin: const EdgeInsets.all(90), + 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)), @@ -89,12 +90,14 @@ class LoginWebPage extends StatelessWidget { child: Form( key: loginBloc.loginFormKey, child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 50, vertical: 25), + padding: EdgeInsets.symmetric( + horizontal: size.width*0.040, + vertical: size.width*0.003), child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.start, children: [ - const SizedBox(height: 15), + const SizedBox(height: 40), const Text( 'Login', style: TextStyle( @@ -102,7 +105,7 @@ class LoginWebPage extends StatelessWidget { fontSize: 24, fontWeight: FontWeight.bold), ), - const SizedBox(height: 40), + SizedBox(height: size.height*0.03), Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, @@ -121,7 +124,7 @@ class LoginWebPage extends StatelessWidget { decoration: textBoxDecoration()!.copyWith( hintText: null,), hint: SizedBox( - width: MediaQuery.sizeOf(context).width * 0.11, + width: size.width * 0.11, child: const Align( alignment: Alignment.centerLeft, child: Text( @@ -142,7 +145,7 @@ class LoginWebPage extends StatelessWidget { }).toList(), onChanged: (String? value) { print(value); - }, + }, ), ) ], @@ -224,7 +227,7 @@ class LoginWebPage extends StatelessWidget { ), ), const SizedBox( - height: 32, + height: 20, ), Row( children: [ @@ -242,7 +245,7 @@ class LoginWebPage extends StatelessWidget { ), ), SizedBox( - width: MediaQuery.sizeOf(context).width * 0.16, + width:size.width * 0.14, child: RichText( text: TextSpan( text: 'Agree to ', @@ -283,9 +286,9 @@ class LoginWebPage extends StatelessWidget { ), ], ), - const SizedBox(height: 30.0), + const SizedBox(height: 20.0), SizedBox( - width: MediaQuery.sizeOf(context).width * 0.2, + width:size.width * 0.2, child: DefaultButton( backgroundColor: loginBloc.isChecked? ColorsManager.btnColor:ColorsManager.grayColor, @@ -301,7 +304,12 @@ class LoginWebPage extends StatelessWidget { }, ), ), - + 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 ),),)],) ], ), ), From 8983d2ce53f044585c606b96902e805aba671572 Mon Sep 17 00:00:00 2001 From: mohammad Date: Tue, 6 Aug 2024 16:50:54 +0300 Subject: [PATCH 3/5] auth changes --- lib/pages/auth/view/forget_password_web_page.dart | 15 +++++++++------ lib/pages/auth/view/login_web_page.dart | 4 ++-- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/lib/pages/auth/view/forget_password_web_page.dart b/lib/pages/auth/view/forget_password_web_page.dart index 7b1e6c93..9a91178c 100644 --- a/lib/pages/auth/view/forget_password_web_page.dart +++ b/lib/pages/auth/view/forget_password_web_page.dart @@ -44,13 +44,14 @@ class ForgetPasswordWebPage extends StatelessWidget { Widget _buildForm(BuildContext context, AuthState state) { final forgetBloc = BlocProvider.of(context); + Size size = MediaQuery.of(context).size; return FirstLayer( second: Center( child: ListView( children: [ Container( - padding:const EdgeInsets.all(30) , - margin: const EdgeInsets.all(90), + 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)), @@ -79,7 +80,9 @@ class ForgetPasswordWebPage extends StatelessWidget { child: Form( key: forgetBloc.forgetFormKey, child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 40, vertical: 25), + padding: EdgeInsets.symmetric( + horizontal: size.width*0.02, + vertical: size.width*0.003), child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.start, @@ -117,7 +120,7 @@ class ForgetPasswordWebPage extends StatelessWidget { hintText: null, ), hint: SizedBox( - width: MediaQuery.sizeOf(context).width * 0.11, + width: size.width * 0.11, child: const Align( alignment: Alignment.centerLeft, child: Text( @@ -231,7 +234,7 @@ class ForgetPasswordWebPage extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ SizedBox( - width: MediaQuery.sizeOf(context).width * 0.2, + width: size.width * 0.2, child: DefaultButton( backgroundColor: ColorsManager.btnColor, child: const Text('Submit'), @@ -249,7 +252,7 @@ class ForgetPasswordWebPage extends StatelessWidget { style: const TextStyle(fontWeight: FontWeight.w700,color: ColorsManager.red ),),), SizedBox(height: 10,), SizedBox( - width: MediaQuery.sizeOf(context).width * 0.2, + width: size.width * 0.2, child: Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, diff --git a/lib/pages/auth/view/login_web_page.dart b/lib/pages/auth/view/login_web_page.dart index 9b073edf..1d92ea85 100644 --- a/lib/pages/auth/view/login_web_page.dart +++ b/lib/pages/auth/view/login_web_page.dart @@ -54,7 +54,7 @@ class LoginWebPage extends StatelessWidget { Widget _buildLoginForm(BuildContext context,AuthState state) { final loginBloc = BlocProvider.of(context); - Size size= MediaQuery.of(context).size; + Size size = MediaQuery.of(context).size; return FirstLayer( second: Center( child: ListView( @@ -91,7 +91,7 @@ class LoginWebPage extends StatelessWidget { key: loginBloc.loginFormKey, child: Padding( padding: EdgeInsets.symmetric( - horizontal: size.width*0.040, + horizontal: size.width*0.02, vertical: size.width*0.003), child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, From 73d49d551897cd35f2aae85c56f828ea5bff96ff Mon Sep 17 00:00:00 2001 From: mohammad Date: Wed, 7 Aug 2024 09:24:41 +0300 Subject: [PATCH 4/5] auth changes --- .../auth/view/forget_password_web_page.dart | 15 ++ lib/pages/auth/view/login_web_page.dart | 219 ++++++++++-------- 2 files changed, 135 insertions(+), 99 deletions(-) diff --git a/lib/pages/auth/view/forget_password_web_page.dart b/lib/pages/auth/view/forget_password_web_page.dart index 9a91178c..4f2a1110 100644 --- a/lib/pages/auth/view/forget_password_web_page.dart +++ b/lib/pages/auth/view/forget_password_web_page.dart @@ -43,11 +43,26 @@ class ForgetPasswordWebPage extends StatelessWidget { } Widget _buildForm(BuildContext context, AuthState state) { + late ScrollController _scrollController; + _scrollController = ScrollController(); + void _scrollToCenter() { + final double middlePosition = _scrollController.position.maxScrollExtent / 2; + _scrollController.animateTo( + middlePosition, + duration: const Duration(seconds: 1), + curve: Curves.easeInOut, + ); + } + WidgetsBinding.instance.addPostFrameCallback((_) { + _scrollToCenter(); + }); final forgetBloc = BlocProvider.of(context); Size size = MediaQuery.of(context).size; return FirstLayer( second: Center( child: ListView( + shrinkWrap: true, + controller: _scrollController, children: [ Container( padding: EdgeInsets.all(size.width*0.02), diff --git a/lib/pages/auth/view/login_web_page.dart b/lib/pages/auth/view/login_web_page.dart index 1d92ea85..2e407e44 100644 --- a/lib/pages/auth/view/login_web_page.dart +++ b/lib/pages/auth/view/login_web_page.dart @@ -15,11 +15,18 @@ import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/pages/home/view/home_page.dart'; import 'package:syncrow_web/utils/style.dart'; -class LoginWebPage extends StatelessWidget { +class LoginWebPage extends StatefulWidget { const LoginWebPage({super.key}); + @override + State createState() => _LoginWebPageState(); +} + +class _LoginWebPageState extends State { + @override Widget build(BuildContext context) { + return Scaffold( body: BlocProvider( create: (BuildContext context) => AuthBloc(), @@ -55,9 +62,23 @@ class LoginWebPage extends StatelessWidget { Widget _buildLoginForm(BuildContext context,AuthState state) { final loginBloc = BlocProvider.of(context); Size size = MediaQuery.of(context).size; + late ScrollController _scrollController; + _scrollController = ScrollController(); + void _scrollToCenter() { + final double middlePosition = _scrollController.position.maxScrollExtent / 2; + _scrollController.animateTo( + middlePosition, + duration: const Duration(seconds: 1), + curve: Curves.easeInOut, + ); + } + WidgetsBinding.instance.addPostFrameCallback((_) { + _scrollToCenter(); + }); return FirstLayer( second: Center( child: ListView( + controller: _scrollController, shrinkWrap: true, children: [ Container( @@ -81,96 +102,96 @@ class LoginWebPage extends StatelessWidget { ), 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), - const Text( - 'Login', - style: TextStyle( - color: Colors.white, - fontSize: 24, - fontWeight: FontWeight.bold), - ), - SizedBox(height: size.height*0.03), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Text( - "Country/Region", - style: smallTextStyle, - ), - const SizedBox(height: 10,), - SizedBox( - child: DropdownButtonFormField( - validator:loginBloc.validateRegion , - icon: const Icon( - Icons.keyboard_arrow_down_outlined, - ), - decoration: textBoxDecoration()!.copyWith( - hintText: null,), - hint: SizedBox( - width: size.width * 0.11, - child: const Align( - alignment: Alignment.centerLeft, - child: Text( - 'Select your region/country', - textAlign: TextAlign.center, - style: TextStyle(fontSize: 14), - overflow: TextOverflow.ellipsis, - ), - ), - ), - isDense: true, - style: const TextStyle(color: Colors.black), - items:loginBloc.regions.map((String region) { - return DropdownMenuItem( - value: region, - child: Text(region), - ); - }).toList(), - onChanged: (String? value) { - print(value); - }, - ), - ) - ], - ), - const SizedBox(height: 20.0), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Text("Email", - style: smallTextStyle, - ), - 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), - ), - ), - ], - ), + 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), + const Text( + 'Login', + style: TextStyle( + color: Colors.white, + fontSize: 24, + fontWeight: FontWeight.bold), + ), + SizedBox(height: size.height*0.03), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + "Country/Region", + style: smallTextStyle, + ), + const SizedBox(height: 10,), + SizedBox( + child: DropdownButtonFormField( + validator:loginBloc.validateRegion , + icon: const Icon( + Icons.keyboard_arrow_down_outlined, + ), + decoration: textBoxDecoration()!.copyWith( + hintText: null,), + hint: SizedBox( + width: size.width * 0.11, + child: const Align( + alignment: Alignment.centerLeft, + child: Text( + 'Select your region/country', + textAlign: TextAlign.center, + style: TextStyle(fontSize: 14), + overflow: TextOverflow.ellipsis, + ), + ), + ), + isDense: true, + style: const TextStyle(color: Colors.black), + items:loginBloc.regions.map((String region) { + return DropdownMenuItem( + value: region, + child: Text(region), + ); + }).toList(), + onChanged: (String? value) { + print(value); + }, + ), + ) + ], + ), + const SizedBox(height: 20.0), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text("Email", + style: smallTextStyle, + ), + 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, @@ -254,7 +275,7 @@ class LoginWebPage extends StatelessWidget { TextSpan( text: '(Terms of Service)', style: const TextStyle( - color: Colors.black,), + color: Colors.black,), recognizer: TapGestureRecognizer() ..onTap = () { loginBloc.launchURL( @@ -304,12 +325,12 @@ class LoginWebPage extends StatelessWidget { }, ), ), - 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: 15.0), + Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ SizedBox(child: Text(loginBloc.validate, + style: const TextStyle(fontWeight: FontWeight.w700,color: ColorsManager.red ),),)],) ], ), ), @@ -318,7 +339,7 @@ class LoginWebPage extends StatelessWidget { const Spacer(), ], ),), - ) + ), ], ), ), From 8e8f810d1e7db6709a0dd4fd498d24c549e4693f Mon Sep 17 00:00:00 2001 From: mohammad Date: Thu, 8 Aug 2024 12:47:12 +0300 Subject: [PATCH 5/5] auth changes --- lib/main.dart | 23 ++++++++++++------- .../auth/view/forget_password_web_page.dart | 11 ++++----- lib/pages/auth/view/login_mobile_page.dart | 8 +++---- lib/pages/auth/view/login_web_page.dart | 21 ++++++----------- lib/pages/common/default_button.dart | 3 +-- lib/utils/style.dart | 6 ----- lib/web_layout/web_app_bar.dart | 7 +++--- 7 files changed, 35 insertions(+), 44 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 6a3f450f..c7b31392 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -2,8 +2,8 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:syncrow_web/pages/auth/bloc/auth_bloc.dart'; import 'package:syncrow_web/pages/auth/view/login_page.dart'; -import 'package:syncrow_web/pages/home/view/home_page.dart'; import 'package:syncrow_web/services/locator.dart'; +import 'package:syncrow_web/utils/color_manager.dart'; Future main() async { WidgetsFlutterBinding.ensureInitialized(); @@ -34,18 +34,25 @@ class MyApp extends StatelessWidget { ), theme: ThemeData( textTheme: const TextTheme( - bodySmall:TextStyle(), - bodyLarge:TextStyle(), - bodyMedium:TextStyle(), + bodySmall: TextStyle( + fontSize: 13, + color: ColorsManager.whiteColors, + fontWeight: FontWeight.bold), + bodyMedium: TextStyle(color: Colors.black87, fontSize: 14), + bodyLarge: TextStyle(fontSize: 16,color: Colors.white), + headlineSmall: TextStyle(color: Colors.black87, fontSize: 18), + headlineMedium: TextStyle(color: Colors.black87, fontSize: 20), + headlineLarge: TextStyle( + color: Colors.white, + fontSize: 24, + fontWeight: FontWeight.bold, + ), ), colorScheme: ColorScheme.fromSeed( seedColor: Colors.deepPurple), // Set up color scheme useMaterial3: true, // Enable Material 3 ), - home: isLoggedIn == 'Success'? - const HomePage() - : - const LoginPage(), + home:LoginPage(), ); } } diff --git a/lib/pages/auth/view/forget_password_web_page.dart b/lib/pages/auth/view/forget_password_web_page.dart index 4f2a1110..d24691b6 100644 --- a/lib/pages/auth/view/forget_password_web_page.dart +++ b/lib/pages/auth/view/forget_password_web_page.dart @@ -11,7 +11,6 @@ import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/style.dart'; class ForgetPasswordWebPage extends StatelessWidget { const ForgetPasswordWebPage({super.key}); - @override Widget build(BuildContext context) { return Scaffold( @@ -113,7 +112,7 @@ class ForgetPasswordWebPage extends StatelessWidget { const SizedBox(height: 10), Text( 'Please fill in your account information to\nretrieve your password', - style: smallTextStyle, + style: Theme.of(context).textTheme.bodySmall, ), const SizedBox(height: 10), Column( @@ -122,7 +121,7 @@ class ForgetPasswordWebPage extends StatelessWidget { children: [ Text( "Country/Region", - style: smallTextStyle, + style: Theme.of(context).textTheme.bodySmall, ), const SizedBox(height: 10), SizedBox( @@ -167,7 +166,7 @@ class ForgetPasswordWebPage extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.start, children: [ Text("Account", - style: smallTextStyle, + style: Theme.of(context).textTheme.bodySmall, ), const SizedBox(height: 10), SizedBox( @@ -186,7 +185,7 @@ class ForgetPasswordWebPage extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.start, children: [ Text("One Time Password", - style: smallTextStyle,), + style: Theme.of(context).textTheme.bodySmall,), const SizedBox(height: 10), SizedBox( child: TextFormField( @@ -225,7 +224,7 @@ class ForgetPasswordWebPage extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.start, children: [ Text("Password", - style: smallTextStyle,), + style: Theme.of(context).textTheme.bodySmall,), const SizedBox(height: 10), SizedBox( child: TextFormField( diff --git a/lib/pages/auth/view/login_mobile_page.dart b/lib/pages/auth/view/login_mobile_page.dart index 3e709735..4cb00cf5 100644 --- a/lib/pages/auth/view/login_mobile_page.dart +++ b/lib/pages/auth/view/login_mobile_page.dart @@ -127,7 +127,7 @@ class LoginMobilePage extends StatelessWidget { children: [ Text( "Country/Region", - style: smallTextStyle, + style: Theme.of(context).textTheme.bodySmall, ), SizedBox( child: DropdownButtonFormField( @@ -168,7 +168,7 @@ class LoginMobilePage extends StatelessWidget { children: [ Text( "Email", - style: smallTextStyle, + style: Theme.of(context).textTheme.bodySmall, ), SizedBox( child: TextFormField( @@ -188,7 +188,7 @@ class LoginMobilePage extends StatelessWidget { children: [ Text( "Password", - style: smallTextStyle, + style: Theme.of(context).textTheme.bodySmall, ), SizedBox( child: TextFormField( @@ -221,7 +221,7 @@ class LoginMobilePage extends StatelessWidget { }, child: Text( "Forgot Password?", - style: smallTextStyle, + style: Theme.of(context).textTheme.bodySmall, ), ), ], diff --git a/lib/pages/auth/view/login_web_page.dart b/lib/pages/auth/view/login_web_page.dart index 2e407e44..401b4b2d 100644 --- a/lib/pages/auth/view/login_web_page.dart +++ b/lib/pages/auth/view/login_web_page.dart @@ -26,7 +26,6 @@ class _LoginWebPageState extends State { @override Widget build(BuildContext context) { - return Scaffold( body: BlocProvider( create: (BuildContext context) => AuthBloc(), @@ -119,13 +118,9 @@ class _LoginWebPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 40), - const Text( + Text( 'Login', - style: TextStyle( - color: Colors.white, - fontSize: 24, - fontWeight: FontWeight.bold), - ), + style:Theme.of(context).textTheme.headlineLarge), SizedBox(height: size.height*0.03), Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -133,7 +128,7 @@ class _LoginWebPageState extends State { children: [ Text( "Country/Region", - style: smallTextStyle, + style: Theme.of(context).textTheme.bodySmall, ), const SizedBox(height: 10,), SizedBox( @@ -164,9 +159,7 @@ class _LoginWebPageState extends State { child: Text(region), ); }).toList(), - onChanged: (String? value) { - print(value); - }, + onChanged: (String? value) {}, ), ) ], @@ -177,7 +170,7 @@ class _LoginWebPageState extends State { mainAxisAlignment: MainAxisAlignment.start, children: [ Text("Email", - style: smallTextStyle, + style: Theme.of(context).textTheme.bodySmall, ), const SizedBox( height: 10, @@ -197,7 +190,7 @@ class _LoginWebPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ - Text("Password", style: smallTextStyle,), + Text("Password", style: Theme.of(context).textTheme.bodySmall,), const SizedBox( height: 10, ), @@ -241,7 +234,7 @@ class _LoginWebPageState extends State { }, child: Text( "Forgot Password?", - style: smallTextStyle, + style: Theme.of(context).textTheme.bodySmall, ), ), ], diff --git a/lib/pages/common/default_button.dart b/lib/pages/common/default_button.dart index 277d18f8..d588acb9 100644 --- a/lib/pages/common/default_button.dart +++ b/lib/pages/common/default_button.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:syncrow_web/utils/color_manager.dart'; -import 'package:syncrow_web/utils/style.dart'; class DefaultButton extends StatelessWidget { const DefaultButton({ @@ -48,7 +47,7 @@ class DefaultButton extends StatelessWidget { ButtonStyle( textStyle: MaterialStateProperty.all( customTextStyle - ?? smallTextStyle.copyWith( + ?? Theme.of(context).textTheme.bodySmall!.copyWith( fontSize: 13, color: foregroundColor, fontWeight: FontWeight.normal diff --git a/lib/utils/style.dart b/lib/utils/style.dart index 70f9d0bd..7260e78d 100644 --- a/lib/utils/style.dart +++ b/lib/utils/style.dart @@ -22,11 +22,5 @@ InputDecoration? textBoxDecoration({bool suffixIcon = false}) => InputDecoration ); -TextStyle appBarTextStyle = -const TextStyle(fontSize: 20, color: ColorsManager.whiteColors); - -TextStyle smallTextStyle = -const TextStyle(fontSize: 13, color: ColorsManager.whiteColors,fontWeight: FontWeight.bold); - Decoration containerDecoration = const BoxDecoration(color: Colors.white,borderRadius: BorderRadius.all(Radius.circular(20))); \ No newline at end of file diff --git a/lib/web_layout/web_app_bar.dart b/lib/web_layout/web_app_bar.dart index c7655eef..7d28032d 100644 --- a/lib/web_layout/web_app_bar.dart +++ b/lib/web_layout/web_app_bar.dart @@ -18,9 +18,8 @@ class WebAppBar extends StatelessWidget { children: [ Expanded( child: Text( - title!,style: const TextStyle( - fontSize: 30, - color: Colors.white),) + title!, + style: Theme.of(context).textTheme.headlineLarge,) ), if (body != null) Expanded( @@ -49,7 +48,7 @@ class WebAppBar extends StatelessWidget { ), ), const SizedBox(width: 10,), - const Text('mohamamd alnemer ',style: TextStyle(fontSize: 16,color: Colors.white),), + Text('mohamamd alnemer ',style:Theme.of(context).textTheme.bodyLarge ,), ], ) ],