added login
This commit is contained in:
parent
8088935aef
commit
6a6ab20eb9
|
|
@ -1,3 +1,4 @@
|
|||
export 'bottom_navbar_cubit/bottom_navbar_cubit.dart';
|
||||
export 'user_bloc/user_bloc.dart';
|
||||
export 'language_bloc/language_bloc.dart';
|
||||
export 'splash_cubit/splash_cubit.dart';
|
||||
export 'user_bloc/user_bloc.dart';
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import '../../core/usecases/usecases.dart';
|
||||
import '../../domain/usecases/splash/splash_usecase.dart';
|
||||
|
||||
// Define the states
|
||||
abstract class SplashState {}
|
||||
|
||||
class SplashInitial extends SplashState {}
|
||||
|
||||
class NavigateToSplash2 extends SplashState {}
|
||||
|
||||
class NavigateToRoot extends SplashState {}
|
||||
|
||||
class SplashCubit extends Cubit<SplashState> {
|
||||
final SplashUseCase _splashUseCase;
|
||||
|
||||
SplashCubit(this._splashUseCase) : super(SplashInitial());
|
||||
|
||||
Future<void> checkToken() async {
|
||||
await Future.delayed(const Duration(seconds: 1)); // Simulating some loading time
|
||||
try {
|
||||
final result = await _splashUseCase(NoParams());
|
||||
result.fold((failure) => emit(NavigateToSplash2()), (result) {
|
||||
result ? emit(NavigateToRoot()) : emit(NavigateToSplash2());
|
||||
});
|
||||
} catch (e) {
|
||||
emit(NavigateToSplash2());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -14,6 +14,9 @@ class MyApp extends StatelessWidget {
|
|||
return MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider(create: (context) => di.sl<NavigationCubit>()),
|
||||
BlocProvider(
|
||||
create: (context) => di.sl<SplashCubit>()..checkToken(),
|
||||
),
|
||||
BlocProvider(
|
||||
create: (context) => di.sl<LanguageBloc>()..add(LanguageInitial()),
|
||||
),
|
||||
|
|
@ -29,7 +32,7 @@ class MyApp extends StatelessWidget {
|
|||
localizationsDelegates: context.localizationDelegates,
|
||||
supportedLocales: context.supportedLocales,
|
||||
locale: context.locale,
|
||||
initialRoute: AppRouter.root,
|
||||
initialRoute: AppRouter.splash,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
const String baseUrl = 'https://rich-jade-mackerel-kit.cyclic.app';
|
||||
const String baseUrl = 'https://192.168.99.64:5001/api';
|
||||
const String defaultApiKey = '';
|
||||
const String defaultSources = '';
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
// App
|
||||
const String appTitle = 'Cargo App';
|
||||
const String appTitle = 'Durnukly ýol';
|
||||
|
||||
// Storage and Databases
|
||||
const String articlesTableName = '';
|
||||
const String databaseName = '';
|
||||
|
||||
// SharedPreferences
|
||||
// locale storage
|
||||
const String activeLang = 'activeLang';
|
||||
// const String token = 'token';
|
||||
|
|
|
|||
|
|
@ -9,6 +9,38 @@ sealed class AppRouter {
|
|||
static const String login = '/login';
|
||||
static const String root = '/root';
|
||||
static const String orderDetails = '/order-details';
|
||||
|
||||
static Route<dynamic> onGenerateRoute(RouteSettings routeSettings) {
|
||||
debugPrint('onGenerateRoute ${routeSettings.name}');
|
||||
switch (routeSettings.name) {
|
||||
case splash:
|
||||
return MaterialPageRoute(builder: (_) => const SplashScreen());
|
||||
case splash2:
|
||||
return MaterialPageRoute(builder: (_) => const Splash2Screen());
|
||||
case login:
|
||||
return MaterialPageRoute(builder: (_) => const LoginScreen());
|
||||
case root:
|
||||
return MaterialPageRoute(builder: (_) => const RootScreen());
|
||||
case orderDetails:
|
||||
return MaterialPageRoute(builder: (_) => const OrderDetailsScreen());
|
||||
|
||||
default:
|
||||
throw const RouteException('Route not found!');
|
||||
}
|
||||
}
|
||||
|
||||
static List<Route<dynamic>> generateInitialRoutes(String initialRoute) {
|
||||
debugPrint('generateInitialRoutes $initialRoute');
|
||||
|
||||
return [
|
||||
MaterialPageRoute(
|
||||
builder: (context) => initialRoute == AppRouter.root ? const RootScreen() : const SplashScreen(),
|
||||
),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// static const String search = '/search';
|
||||
// static const String filter = '/filter';
|
||||
// static const String signup = '/signup';
|
||||
|
|
@ -25,21 +57,8 @@ sealed class AppRouter {
|
|||
// static const String orders = '/orders';
|
||||
// static const String notifications = '/notifications';
|
||||
|
||||
static Route<dynamic> onGenerateRoute(RouteSettings routeSettings) {
|
||||
debugPrint('onGenerateRoute ${routeSettings.name}');
|
||||
switch (routeSettings.name) {
|
||||
case splash:
|
||||
return MaterialPageRoute(builder: (_) => const SplashScreen());
|
||||
case splash2:
|
||||
return MaterialPageRoute(builder: (_) => const Splash2Screen());
|
||||
case login:
|
||||
return MaterialPageRoute(builder: (_) => const LoginScreen());
|
||||
case root:
|
||||
return MaterialPageRoute(builder: (_) => const RootScreen());
|
||||
case orderDetails:
|
||||
// ProductEntity product = routeSettings.arguments as ProductEntity;
|
||||
return MaterialPageRoute(builder: (_) => const OrderDetailsScreen());
|
||||
// case search:
|
||||
|
||||
// case search:
|
||||
// return MaterialPageRoute(builder: (_) => const SearchScreen());
|
||||
// case filter:
|
||||
// return MaterialPageRoute(builder: (_) => const FilterScreen());
|
||||
|
|
@ -82,21 +101,4 @@ sealed class AppRouter {
|
|||
// case orders:
|
||||
// return MaterialPageRoute(builder: (_) => const OrdersScreen());
|
||||
// case notifications:
|
||||
// return MaterialPageRoute(builder: (_) => const NotificationsScreen());
|
||||
default:
|
||||
throw const RouteException('Route not found!');
|
||||
}
|
||||
}
|
||||
|
||||
static List<Route<dynamic>> generateInitialRoutes(String initialRoute) {
|
||||
debugPrint('generateInitialRoutes $initialRoute');
|
||||
|
||||
return [
|
||||
MaterialPageRoute(builder: (context) => const RootScreen()),
|
||||
if (initialRoute != AppRouter.root)
|
||||
MaterialPageRoute(
|
||||
builder: (context) => const SplashScreen(),
|
||||
),
|
||||
];
|
||||
}
|
||||
}
|
||||
// return MaterialPageRoute(builder: (_) => const NotificationsScreen());
|
||||
|
|
@ -1 +1,8 @@
|
|||
// TODO Implement this library.
|
||||
class FormValidator {
|
||||
static String? validateField(String? val) {
|
||||
if (val == null || val.isEmpty) {
|
||||
return 'This field can\'t be empty';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class Keyboard {
|
||||
static hide(BuildContext context) {
|
||||
FocusScope.of(context).requestFocus(FocusNode());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,2 @@
|
|||
export 'form_validator.dart';
|
||||
|
||||
class FormValidator {
|
||||
static String? validateField(String? val) {
|
||||
if (val == null || val.isEmpty) {
|
||||
return 'This field can\'t be empty';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
export 'keyboard.dart';
|
||||
|
|
|
|||
|
|
@ -20,9 +20,20 @@ class UserRemoteDataSourceImpl implements UserRemoteDataSource {
|
|||
Future<AuthenticationResponseModel> signIn(SignInParams params) async {
|
||||
debugPrint('signIn');
|
||||
|
||||
const data = '''
|
||||
try {
|
||||
final response = await client.post(Uri.parse('$baseUrl/Authentication/Authenticate'),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'accept': '*/*',
|
||||
},
|
||||
body: json.encode({
|
||||
'UserName': params.username,
|
||||
'Password': '', // params.password,
|
||||
}));
|
||||
if (response.statusCode == 200) {
|
||||
const userData = '''
|
||||
{
|
||||
"token": "exampleToken123",
|
||||
"token": "",
|
||||
"user": {
|
||||
"_id": "user123",
|
||||
"firstName": "John",
|
||||
|
|
@ -31,23 +42,21 @@ class UserRemoteDataSourceImpl implements UserRemoteDataSource {
|
|||
}
|
||||
}
|
||||
''';
|
||||
AuthenticationResponseModel user = authenticationResponseModelFromJson(userData);
|
||||
|
||||
return authenticationResponseModelFromJson(data);
|
||||
/* final response = await client.post(Uri.parse('$baseUrl/authentication/local/sign-in'),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: json.encode({
|
||||
'identifier': params.username,
|
||||
'password': params.password,
|
||||
}));
|
||||
if (response.statusCode == 200) {
|
||||
return authenticationResponseModelFromJson(response.body);
|
||||
} else if (response.statusCode == 400 || response.statusCode == 401) {
|
||||
throw CredentialFailure();
|
||||
} else {
|
||||
// Update the token value
|
||||
AuthenticationResponseModel updatedUser = user.copyWith(token: response.body);
|
||||
|
||||
return updatedUser;
|
||||
} else if (response.statusCode == 400 || response.statusCode == 401) {
|
||||
throw CredentialFailure();
|
||||
} else {
|
||||
throw ServerException();
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('e $e');
|
||||
throw ServerException();
|
||||
} */
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
|||
|
|
@ -25,4 +25,14 @@ class AuthenticationResponseModel {
|
|||
'token': token,
|
||||
'user': user.toJson(),
|
||||
};
|
||||
|
||||
AuthenticationResponseModel copyWith({
|
||||
String? token,
|
||||
UserModel? user,
|
||||
}) {
|
||||
return AuthenticationResponseModel(
|
||||
token: token ?? this.token,
|
||||
user: user ?? this.user,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
export 'user_repository_impl.dart';
|
||||
export 'splash_repository_impl.dart';
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
import 'package:dartz/dartz.dart';
|
||||
|
||||
import '../../core/core.dart';
|
||||
import '../../domain/domain.dart';
|
||||
import '../data.dart';
|
||||
|
||||
class SplashRepositoryImpl implements SplashRepository {
|
||||
final UserLocalDataSource localDataSource;
|
||||
|
||||
SplashRepositoryImpl({required this.localDataSource});
|
||||
|
||||
@override
|
||||
Future<Either<Failure, bool>> isTokenAvailable() async {
|
||||
try {
|
||||
final isAvl = await localDataSource.isTokenAvailable();
|
||||
return Right(isAvl);
|
||||
} on CacheFailure {
|
||||
return Left(CacheFailure());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ import 'package:get_it/get_it.dart';
|
|||
import 'common.dart';
|
||||
import 'cubits.dart';
|
||||
import 'language.dart';
|
||||
import 'splash.dart';
|
||||
import 'user.dart';
|
||||
|
||||
final sl = GetIt.instance;
|
||||
|
|
@ -10,8 +11,11 @@ final sl = GetIt.instance;
|
|||
// Main Initialization
|
||||
Future<void> init() async {
|
||||
// Register features
|
||||
|
||||
registerUserFeature();
|
||||
registerLanguageFeature();
|
||||
registerSplashFeature();
|
||||
|
||||
// registerCategoryFeature();
|
||||
// registerProductFeature();
|
||||
// registerDeliveryInfoFeature();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
import 'package:cargo/data/data.dart';
|
||||
import 'package:cargo/domain/domain.dart';
|
||||
|
||||
import '../application/splash_cubit/splash_cubit.dart';
|
||||
import 'di.dart';
|
||||
|
||||
void registerSplashFeature() {
|
||||
// Splash cubit and Use Cases
|
||||
sl.registerFactory(() => SplashCubit(sl()));
|
||||
sl.registerLazySingleton(() => SplashUseCase(sl()));
|
||||
|
||||
// Splash Repository and Data Sources
|
||||
sl.registerLazySingleton<SplashRepository>(
|
||||
() => SplashRepositoryImpl(
|
||||
localDataSource: sl(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
@ -1 +1,2 @@
|
|||
export 'user_repository.dart';
|
||||
export 'splash_repository.dart';
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
import 'package:dartz/dartz.dart';
|
||||
|
||||
import '../../core/core.dart';
|
||||
|
||||
abstract class SplashRepository {
|
||||
Future<Either<Failure, bool>> isTokenAvailable();
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
import 'package:dartz/dartz.dart';
|
||||
|
||||
import '../../../core/core.dart';
|
||||
import '../../domain.dart';
|
||||
|
||||
class SplashUseCase implements UseCase<bool, NoParams> {
|
||||
final SplashRepository repository;
|
||||
SplashUseCase(this.repository);
|
||||
|
||||
@override
|
||||
Future<Either<Failure, bool>> call(NoParams params) async {
|
||||
return await repository.isTokenAvailable();
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +1,2 @@
|
|||
export 'user/user.dart';
|
||||
export 'splash/splash_usecase.dart';
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
|
@ -27,6 +29,8 @@ Future<void> main() async {
|
|||
statusBarBrightness: Brightness.dark,
|
||||
));
|
||||
|
||||
HttpOverrides.global = MyHttpOverrides();
|
||||
|
||||
runApp(
|
||||
EasyLocalization(
|
||||
supportedLocales: const [
|
||||
|
|
@ -48,3 +52,11 @@ Future<void> main() async {
|
|||
// 4 create repository implementation
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,77 +1,146 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
|
||||
import '../../application/application.dart';
|
||||
import '../../configs/configs.dart';
|
||||
import '../../core/core.dart';
|
||||
|
||||
class SplashScreen extends StatefulWidget {
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class SplashScreen extends StatelessWidget {
|
||||
const SplashScreen({super.key});
|
||||
|
||||
@override
|
||||
State<SplashScreen> createState() => _SplashScreenState();
|
||||
}
|
||||
|
||||
class _SplashScreenState extends State<SplashScreen> {
|
||||
void _nextScreen() {
|
||||
Future.delayed(const Duration(seconds: 1), () {
|
||||
Navigator.of(context).pushNamedAndRemoveUntil(
|
||||
AppRouter.splash2,
|
||||
(route) => false,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||
_nextScreen();
|
||||
});
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
App.init(context);
|
||||
return Scaffold(
|
||||
body: Container(
|
||||
decoration: const BoxDecoration(
|
||||
gradient: RadialGradient(
|
||||
center: Alignment.center,
|
||||
radius: 1.0,
|
||||
colors: [
|
||||
Color(0xFF5468FF), // Lighter blue in the center
|
||||
AppColors.primary, // Darker blue at the edges
|
||||
],
|
||||
),
|
||||
),
|
||||
child: SafeArea(
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
AppAssets.logo,
|
||||
height: AppDimensions.normalize(30),
|
||||
),
|
||||
Space.yf(0.80),
|
||||
Text(
|
||||
appTitle,
|
||||
style: AppText.h1b?.copyWith(
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
Space.yf(0.30),
|
||||
Text(
|
||||
'Довезём всё!',
|
||||
style: AppText.b1?.copyWith(
|
||||
color: AppColors.yellow,
|
||||
),
|
||||
),
|
||||
return BlocListener<SplashCubit, SplashState>(
|
||||
listener: (context, state) {
|
||||
Keyboard.hide(context);
|
||||
if (state is NavigateToSplash2) {
|
||||
Navigator.of(context).pushNamedAndRemoveUntil(
|
||||
AppRouter.splash2,
|
||||
(route) => false,
|
||||
);
|
||||
} else if (state is NavigateToRoot) {
|
||||
Navigator.of(context).pushNamedAndRemoveUntil(
|
||||
AppRouter.root,
|
||||
(route) => false,
|
||||
);
|
||||
}
|
||||
},
|
||||
child: Scaffold(
|
||||
body: Container(
|
||||
decoration: const BoxDecoration(
|
||||
gradient: RadialGradient(
|
||||
center: Alignment.center,
|
||||
radius: 1.0,
|
||||
colors: [
|
||||
Color(0xFF5468FF), // Lighter blue in the center
|
||||
AppColors.primary, // Darker blue at the edges
|
||||
],
|
||||
),
|
||||
),
|
||||
child: SafeArea(
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
AppAssets.logo,
|
||||
height: AppDimensions.normalize(30),
|
||||
),
|
||||
Space.yf(0.80),
|
||||
Text(
|
||||
appTitle,
|
||||
style: AppText.h1b?.copyWith(
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
Space.yf(0.30),
|
||||
Text(
|
||||
'Довезём всё!',
|
||||
style: AppText.b1?.copyWith(
|
||||
color: AppColors.yellow,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// class SplashScreen extends StatefulWidget {
|
||||
// const SplashScreen({super.key});
|
||||
|
||||
// @override
|
||||
// State<SplashScreen> createState() => _SplashScreenState();
|
||||
// }
|
||||
|
||||
// class _SplashScreenState extends State<SplashScreen> {
|
||||
// void _nextScreen() {
|
||||
// Future.delayed(const Duration(seconds: 1), () {
|
||||
// Navigator.of(context).pushNamedAndRemoveUntil(
|
||||
// AppRouter.splash2,
|
||||
// (route) => false,
|
||||
// );
|
||||
// });
|
||||
// }
|
||||
|
||||
// @override
|
||||
// void initState() {
|
||||
// WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||
// _nextScreen();
|
||||
// });
|
||||
// super.initState();
|
||||
// }
|
||||
|
||||
// @override
|
||||
// Widget build(BuildContext context) {
|
||||
// App.init(context);
|
||||
// return Scaffold(
|
||||
// body: Container(
|
||||
// decoration: const BoxDecoration(
|
||||
// gradient: RadialGradient(
|
||||
// center: Alignment.center,
|
||||
// radius: 1.0,
|
||||
// colors: [
|
||||
// Color(0xFF5468FF), // Lighter blue in the center
|
||||
// AppColors.primary, // Darker blue at the edges
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// child: SafeArea(
|
||||
// child: Center(
|
||||
// child: Column(
|
||||
// mainAxisAlignment: MainAxisAlignment.center,
|
||||
// children: [
|
||||
// SvgPicture.asset(
|
||||
// AppAssets.logo,
|
||||
// height: AppDimensions.normalize(30),
|
||||
// ),
|
||||
// Space.yf(0.80),
|
||||
// Text(
|
||||
// appTitle,
|
||||
// style: AppText.h1b?.copyWith(
|
||||
// color: Colors.white,
|
||||
// ),
|
||||
// ),
|
||||
// Space.yf(0.30),
|
||||
// Text(
|
||||
// 'Довезём всё!',
|
||||
// style: AppText.b1?.copyWith(
|
||||
// color: AppColors.yellow,
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
|
|
|||
Loading…
Reference in New Issue