diff --git a/lib/application/user_bloc/user_bloc.dart b/lib/application/user_bloc/user_bloc.dart index 61145be..ee22955 100644 --- a/lib/application/user_bloc/user_bloc.dart +++ b/lib/application/user_bloc/user_bloc.dart @@ -31,6 +31,7 @@ class UserBloc extends Bloc { void _onSignIn(SignInUser event, Emitter emit) async { try { emit(UserLoading()); + // await Future.delayed(const Duration(seconds: 3)); final result = await _signInUseCase(event.params); result.fold( (failure) => emit(UserLoggedFail(failure)), @@ -100,7 +101,7 @@ class UserBloc extends Bloc { FutureOr _onGetUser(GetUser event, Emitter emit) async { try { emit(UserLoading()); - + // await Future.delayed(const Duration(seconds: 3)); final user = await _getUserFromCacheOrRemote(); emit(UserFetched(user)); } catch (failure) { diff --git a/lib/configs/app_dimensions.dart b/lib/configs/app_dimensions.dart index 1d267b3..f3101bf 100644 --- a/lib/configs/app_dimensions.dart +++ b/lib/configs/app_dimensions.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'dart:ui' as ui; +// import 'dart:ui' as ui; import 'ui.dart'; class AppDimensions { diff --git a/lib/core/app/app.dart b/lib/core/app/app.dart index 6d4f840..78a3444 100644 --- a/lib/core/app/app.dart +++ b/lib/core/app/app.dart @@ -33,6 +33,11 @@ class MyApp extends StatelessWidget { supportedLocales: context.supportedLocales, locale: context.locale, initialRoute: AppRouter.splash, + theme: ThemeData( + primarySwatch: CustomColors.primarySwatch, + useMaterial3: false, + primaryColor: AppColors.primary, + ), ), ); } diff --git a/lib/core/constants/colors.dart b/lib/core/constants/colors.dart index ee1b71b..8255390 100644 --- a/lib/core/constants/colors.dart +++ b/lib/core/constants/colors.dart @@ -9,3 +9,35 @@ sealed class AppColors { static const Color darkGrey = Color(0xFF57575C); static const Color lightGrey = Color(0xFFE5E5E6); } + +class CustomColors { + static const Color primaryColor = Color(0xFF343FDE); + + // Create a MaterialColor using the primary color + static MaterialColor primarySwatch = MaterialColor( + _primaryValue, + { + 50: _createShade(0.1), + 100: _createShade(0.2), + 200: _createShade(0.3), + 300: _createShade(0.4), + 400: _createShade(0.5), + 500: primaryColor, + 600: _createShade(0.7), + 700: _createShade(0.8), + 800: _createShade(0.9), + 900: _createShade(1.0), + }, + ); + + static const int _primaryValue = 0xFF343FDE; + + // Create a shade of the primary color + static Color _createShade(double strength) { + final double t = strength; + final int r = ((1 - t) * 255 + t * 52).toInt(); + final int g = ((1 - t) * 255 + t * 63).toInt(); + final int b = ((1 - t) * 255 + t * 222).toInt(); + return Color.fromARGB(255, r, g, b); + } +} diff --git a/lib/core/utils/http_override.dart b/lib/core/utils/http_override.dart new file mode 100644 index 0000000..b695d8e --- /dev/null +++ b/lib/core/utils/http_override.dart @@ -0,0 +1,9 @@ +import 'dart:io'; + +class MyHttpOverrides extends HttpOverrides { + @override + HttpClient createHttpClient(SecurityContext? context) { + return super.createHttpClient(context) + ..badCertificateCallback = (X509Certificate cert, String host, int port) => true; + } +} diff --git a/lib/core/utils/utils.dart b/lib/core/utils/utils.dart index d731ea2..0a61a4d 100644 --- a/lib/core/utils/utils.dart +++ b/lib/core/utils/utils.dart @@ -1,3 +1,4 @@ export 'form_validator.dart'; export 'keyboard.dart'; export 'error_util.dart'; +export 'http_override.dart'; diff --git a/lib/main.dart b/lib/main.dart index 4986ce1..317d2a3 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -13,8 +13,6 @@ Future main() async { WidgetsFlutterBinding.ensureInitialized(); await EasyLocalization.ensureInitialized(); - // await GetStorage.init(); - await di.init(); Bloc.observer = MyBlocObserver(); @@ -53,10 +51,3 @@ Future main() async { // 5 create data source // 6 add di register -class MyHttpOverrides extends HttpOverrides { - @override - HttpClient createHttpClient(SecurityContext? context) { - return super.createHttpClient(context) - ..badCertificateCallback = (X509Certificate cert, String host, int port) => true; - } -} diff --git a/lib/presentation/screens/login.dart b/lib/presentation/screens/login.dart index 5358d2d..2d0a27d 100644 --- a/lib/presentation/screens/login.dart +++ b/lib/presentation/screens/login.dart @@ -170,13 +170,22 @@ class _LoginScreenState extends State { _nextScreen(); } else if (state is UserLoggedFail) { if (state.failure is CredentialFailure) { - showCredentialErrorDialog(context); + showErrorDialog( + context: context, + header: 'Invalid credentials', + body: 'Username or Password Wrong!', + ); } else { showAuthErrorDialog(context); } } }, builder: (context, state) { + if (state is UserLoading) { + return const Center( + child: CircularProgressIndicator(), + ); + } return SizedBox( width: double.infinity, child: AppButton( @@ -184,6 +193,9 @@ class _LoginScreenState extends State { btnColor: AppColors.primary, onPressed: () { if (_formKey.currentState!.validate()) { + Keyboard.hide(context); + + /// sign in context.read().add( SignInUser( SignInParams( @@ -198,7 +210,7 @@ class _LoginScreenState extends State { ), ); }, - ) + ), ], ), ), diff --git a/lib/presentation/screens/profile.dart b/lib/presentation/screens/profile.dart index b2b72b6..a8ce8fb 100644 --- a/lib/presentation/screens/profile.dart +++ b/lib/presentation/screens/profile.dart @@ -18,8 +18,8 @@ class ProfileScreen extends StatefulWidget { class _ProfileScreenState extends State { @override void initState() { - context.read().add(GetUser()); super.initState(); + context.read().add(GetUser()); } @override @@ -27,7 +27,12 @@ class _ProfileScreenState extends State { App.init(context); return Scaffold( backgroundColor: AppColors.surface, - body: BlocBuilder( + body: BlocConsumer( + listener: (context, state) { + if (state is UserLoggedOut || state is UserLoggedFail) { + _navigateToLoginScreen(context); + } + }, builder: (context, state) { if (state is UserLoading) { return const Center(child: CircularProgressIndicator()); @@ -80,7 +85,6 @@ class _ProfileScreenState extends State { RowWidget( text: user.fullName, leadingIcon: Icons.person_2_outlined, - // trailingIcon: Icons.mode_edit_outlined, ), /// gap @@ -90,7 +94,6 @@ class _ProfileScreenState extends State { RowWidget( text: user.phone, leadingIcon: Icons.phone_android_outlined, - // trailingIcon: Icons.mode_edit_outlined, ), ], ), @@ -168,7 +171,9 @@ class _ProfileScreenState extends State { Align( alignment: Alignment.center, child: TextButton( - onPressed: () {}, + onPressed: () { + context.read().add(SignOutUser()); + }, child: Text( 'Şahsy otagdan çykmak', style: AppText.b1!.copyWith( @@ -185,6 +190,15 @@ class _ProfileScreenState extends State { ), ); } + + void _navigateToLoginScreen(BuildContext context) { + WidgetsBinding.instance.addPostFrameCallback((_) { + Navigator.of(context).pushNamedAndRemoveUntil( + AppRouter.login, + (route) => false, + ); + }); + } } class RowWidget extends StatelessWidget { diff --git a/lib/presentation/widgets/credential_failure_dialog.dart b/lib/presentation/widgets/credential_failure_dialog.dart deleted file mode 100644 index 53f7e26..0000000 --- a/lib/presentation/widgets/credential_failure_dialog.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'package:flutter/material.dart'; - -import '../../configs/configs.dart'; -import '../../core/core.dart'; - -Future showCredentialErrorDialog(BuildContext context) async { - return showDialog( - context: context, - barrierDismissible: false, - builder: (BuildContext context) { - return Dialog( - child: Container( - height: AppDimensions.normalize(60), - padding: Space.all(1, .5), - child: Center( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Username/Password Wrong!', - style: AppText.b1b, - ), - Space.yf(.5), - Text( - 'Try Again!', - style: AppText.b1, - ), - Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - TextButton( - onPressed: () { - Navigator.pop(context); - }, - child: Text( - 'Dismiss', - style: AppText.h3b?.copyWith( - color: AppColors.primary, - ), - )) - ], - ) - ], - ), - ), - ), - ); - }); -} diff --git a/lib/presentation/widgets/error_dialog.dart b/lib/presentation/widgets/error_dialog.dart new file mode 100644 index 0000000..ca046dc --- /dev/null +++ b/lib/presentation/widgets/error_dialog.dart @@ -0,0 +1,69 @@ +import 'package:flutter/material.dart'; + +import '../../configs/configs.dart'; +import '../../core/core.dart'; + +Future showErrorDialog({ + required BuildContext context, + required String header, + required String body, + String dismissButtonText = 'Dismiss', + VoidCallback? onDismiss, +}) async { + return showDialog( + context: context, + barrierDismissible: false, + builder: (BuildContext context) { + return Dialog( + child: Container( + padding: Space.all(1, .5), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16), + decoration: const BoxDecoration( + color: AppColors.primary, + borderRadius: BorderRadius.all( + Radius.circular(12), + ), + ), + child: Text( + header, + style: AppText.h3b?.copyWith(color: Colors.white), + ), + ), + Padding( + padding: const EdgeInsets.all(16.0), + child: Text( + body, + style: AppText.b1, + ), + ), + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + TextButton( + onPressed: () { + Navigator.pop(context); + if (onDismiss != null) { + onDismiss(); + } + }, + child: Text( + dismissButtonText, + style: AppText.h3b?.copyWith( + color: AppColors.primary, + ), + ), + ), + ], + ), + ], + ), + ), + ); + }, + ); +} diff --git a/lib/presentation/widgets/widgets.dart b/lib/presentation/widgets/widgets.dart index 429b7e3..625a21e 100644 --- a/lib/presentation/widgets/widgets.dart +++ b/lib/presentation/widgets/widgets.dart @@ -1,7 +1,7 @@ export 'auth_error_dialog.dart'; export 'bottom_navbar.dart'; export 'button.dart'; -export 'credential_failure_dialog.dart'; +export 'error_dialog.dart'; export 'info_card.dart'; export 'location_card.dart'; export 'order_card.dart';