diff --git a/lib/main.dart b/lib/main.dart index b0cbeab9..d52c6541 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -4,6 +4,7 @@ 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(); @@ -33,14 +34,23 @@ class MyApp extends StatelessWidget { }, ), theme: ThemeData( - colorScheme: ColorScheme.fromSeed( - seedColor: Colors.deepPurple), // Set up color scheme + textTheme: const TextTheme( + 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: isLoggedIn == 'Success' ? const HomePage() : const LoginPage(), ); } } diff --git a/lib/pages/auth/bloc/auth_bloc.dart b/lib/pages/auth/bloc/auth_bloc.dart index c1e21c71..00f6227f 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(); @@ -103,12 +98,13 @@ class AuthBloc extends Bloc { String newPassword = ''; String maskedEmail = ''; String otpCode = ''; + String validate = ''; static Token token = Token.emptyConstructor(); static UserModel? user; bool showValidationMessage = false; void _login(LoginButtonPressed event, Emitter emit) async { - emit(LoginLoading()); + emit(AuthLoading()); if (isChecked) { try { if (event.username.isEmpty || event.password.isEmpty) { @@ -123,12 +119,12 @@ class AuthBloc extends Bloc { ), ); } catch (failure) { + validate='Something went wrong'; emit(const LoginFailure(error: 'Something went wrong')); // emit(LoginFailure(error: failure.toString())); return; } if (token.accessTokenIsNotEmpty) { - debugPrint('token: ${token.accessToken}'); FlutterSecureStorage storage = const FlutterSecureStorage(); await storage.write( key: Token.loginAccessTokenKey, value: token.accessToken); @@ -148,7 +144,7 @@ class AuthBloc extends Bloc { } checkBoxToggle(CheckBoxEvent event, Emitter emit,) { - emit(LoginLoading()); + emit(AuthLoading()); isChecked = event.newValue!; emit(LoginInitial()); } @@ -161,15 +157,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 +314,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..4b6359eb 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 {} @@ -35,13 +35,13 @@ class LoginInvalid extends AuthState { List get props => [error]; } -class InitialForgetState extends AuthState{} +class InitialForgetState extends AuthState {} -class LoadingForgetState extends AuthState{} +class LoadingForgetState extends AuthState {} -class SuccessForgetState extends AuthState{} +class SuccessForgetState extends AuthState {} -class PasswordVisibleState extends AuthState{} +class PasswordVisibleState extends AuthState {} class FailureForgetState extends AuthState { final String error; @@ -51,7 +51,7 @@ class FailureForgetState extends AuthState { } class TimerState extends AuthState { - final bool isButtonEnabled ; + final bool isButtonEnabled; final int remainingTime; const TimerState({required this.isButtonEnabled, required this.remainingTime}); @@ -60,7 +60,6 @@ class TimerState extends AuthState { List get props => [isButtonEnabled, remainingTime]; } - class AuthError extends AuthState { final String message; String? code; @@ -70,9 +69,7 @@ class AuthError extends AuthState { class AuthTokenError extends AuthError { AuthTokenError({required super.message, super.code}); } + 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..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( @@ -19,9 +18,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) { @@ -45,234 +42,266 @@ 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: 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( + shrinkWrap: true, + 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), + 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: 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: smallTextStyle, + children: [ + const SizedBox(height: 10), + const Text( + 'Forget Password', + style: TextStyle( + color: Colors.white, + fontSize: 24, + fontWeight: FontWeight.bold), ), 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, + Text( + 'Please fill in your account information to\nretrieve your password', + style: Theme.of(context).textTheme.bodySmall, + ), + const SizedBox(height: 10), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + "Country/Region", + style: Theme.of(context).textTheme.bodySmall, ), - 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: size.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: Theme.of(context).textTheme.bodySmall, ), - 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: Theme.of(context).textTheme.bodySmall,), + 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), - 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', + 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: forgetBloc.passwordValidator, + keyboardType: TextInputType.visiblePassword, + controller: forgetBloc.forgetPasswordController, + decoration: textBoxDecoration()!.copyWith( + hintText: 'At least 8 characters', + ), + style: const TextStyle(color: Colors.black), + ), ), - style: const TextStyle(color: Colors.black), - ), + ], ), + const SizedBox( + height: 10, + ), + const SizedBox(height: 20.0), + Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox( + width: size.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: size.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 4c38f18e..a2877bf5 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); @@ -128,7 +127,7 @@ class LoginMobilePage extends StatelessWidget { children: [ Text( "Country/Region", - style: smallTextStyle, + style: Theme.of(context).textTheme.bodySmall, ), SizedBox( child: DropdownButtonFormField( @@ -169,7 +168,7 @@ class LoginMobilePage extends StatelessWidget { children: [ Text( "Email", - style: smallTextStyle, + style: Theme.of(context).textTheme.bodySmall, ), SizedBox( child: TextFormField( @@ -189,7 +188,7 @@ class LoginMobilePage extends StatelessWidget { children: [ Text( "Password", - style: smallTextStyle, + style: Theme.of(context).textTheme.bodySmall, ), SizedBox( child: TextFormField( @@ -222,7 +221,7 @@ class LoginMobilePage extends StatelessWidget { }, child: Text( "Forgot Password?", - style: smallTextStyle, + style: Theme.of(context).textTheme.bodySmall, ), ), ], @@ -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_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 59b26946..1a473df7 100644 --- a/lib/pages/auth/view/login_web_page.dart +++ b/lib/pages/auth/view/login_web_page.dart @@ -15,14 +15,20 @@ 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: (context) => AuthBloc(), + create: (BuildContext context) => AuthBloc(), child: BlocConsumer( listener: (context, state) { if (state is LoginSuccess) { @@ -41,7 +47,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); @@ -54,365 +60,282 @@ 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: 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( + 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: 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( + 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: 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, + 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, ), - decoration: textBoxDecoration()!.copyWith( - hintText: null, + 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) {}, + ), + ) + ], + ), + const SizedBox(height: 20.0), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text("Email", + style: Theme.of(context).textTheme.bodySmall, ), - hint: const Align( - alignment: Alignment.centerLeft, - child: Text( - 'Select your region/country', - textAlign: TextAlign.center, + 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), ), ), - 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: 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: 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: Theme.of(context).textTheme.bodySmall, ), ), - ) - ), - 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: 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: 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'); - }, + 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( + 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: 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: 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/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/pages/home/view/home_page_mobile.dart b/lib/pages/home/view/home_page_mobile.dart index 02159c31..1b868906 100644 --- a/lib/pages/home/view/home_page_mobile.dart +++ b/lib/pages/home/view/home_page_mobile.dart @@ -13,7 +13,7 @@ class HomeMobilePage extends StatelessWidget { Widget build(BuildContext context) { Size size = MediaQuery.of(context).size; return WebScaffold( - enableMenuSideba:false , + enableMenuSideba: false, appBarTitle: Row( children: [ SvgPicture.asset( @@ -51,11 +51,11 @@ class HomeMobilePage extends StatelessWidget { childAspectRatio: 1.5, ), itemBuilder: (context, index) { - return HomeCard( - index:index, - active:ceilingSensorButtons[index]['active'], - name: ceilingSensorButtons[index]['title'], - img:ceilingSensorButtons[index]['icon'] , + return HomeCard( + index: index, + active: homeItems[index]['active'], + name: homeItems[index]['title'], + img: homeItems[index]['icon'], onTap: () {}, ); }, @@ -69,8 +69,7 @@ class HomeMobilePage extends StatelessWidget { ); } - dynamic ceilingSensorButtons = - [ + dynamic homeItems = [ { 'title': 'Access', 'icon': Assets.accessIcon, @@ -84,7 +83,7 @@ class HomeMobilePage extends StatelessWidget { }, { 'title': 'Devices', - 'icon':Assets.devicesIcon, + 'icon': Assets.devicesIcon, 'active': true, }, { @@ -108,11 +107,12 @@ class HomeMobilePage extends StatelessWidget { 'icon': Assets.integrationsIcon, 'color': ColorsManager.slidingBlueColor.withOpacity(0.2), 'active': false, - }, { - 'title': 'Asset', - 'icon': Assets.assetIcon, - 'color': ColorsManager.slidingBlueColor.withOpacity(0.2), - 'active': false, - }, + }, + { + 'title': 'Asset', + 'icon': Assets.assetIcon, + 'color': ColorsManager.slidingBlueColor.withOpacity(0.2), + 'active': false, + }, ]; } 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'; } 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 c69350f2..4163e168 100644 --- a/lib/web_layout/web_app_bar.dart +++ b/lib/web_layout/web_app_bar.dart @@ -2,28 +2,23 @@ import 'package:flutter/material.dart'; import 'package:syncrow_web/utils/color_manager.dart'; class WebAppBar extends StatelessWidget { - final Widget? title; - final List? body; - const WebAppBar({super.key,this.title,this.body}); + final Widget? title; + final List? body; + const WebAppBar({super.key, this.title, this.body}); @override Widget build(BuildContext context) { return Container( height: 120, - decoration: const BoxDecoration(color:ColorsManager.secondaryColor ), + decoration: const BoxDecoration(color: ColorsManager.secondaryColor), padding: const EdgeInsets.all(10), child: Expanded( child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - SizedBox(width: 40,), Expanded( - child: title! - // Text( - // title!,style: const TextStyle( - // fontSize: 30, - // color: Colors.white),) - ), + child: title!, + ), if (body != null) Expanded( flex: 2, @@ -32,31 +27,36 @@ class WebAppBar extends StatelessWidget { children: body!, ), ), - const Row( + Row( children: [ - SizedBox(width: 10,), - SizedBox.square( - dimension: 40, - child: CircleAvatar( - backgroundColor: Colors.white, - child: SizedBox.square( - dimension: 35, - child: CircleAvatar( - backgroundColor: Colors.grey, - child: FlutterLogo(), - ), - ), - ), - ), - const SizedBox(width: 10,), - const Text('mohamamd alnemer ',style: TextStyle(fontSize: 16,color: Colors.white),), - Icon(Icons.arrow_drop_down,color: ColorsManager.whiteColors,), - SizedBox(width: 40,) + const SizedBox( + width: 10, + ), + const SizedBox.square( + dimension: 40, + child: CircleAvatar( + backgroundColor: Colors.white, + child: SizedBox.square( + dimension: 35, + child: CircleAvatar( + backgroundColor: Colors.grey, + child: FlutterLogo(), + ), + ), + ), + ), + const SizedBox( + width: 10, + ), + Text( + 'mohamamd alnemer ', + style: Theme.of(context).textTheme.bodyLarge, + ), ], ) ], ), - ) , + ), ); } -} \ No newline at end of file +}