delete added
This commit is contained in:
parent
efdf52cb2e
commit
0739f345a9
|
|
@ -51,5 +51,14 @@
|
|||
"error_message": "Что-то пошло не так. Пожалуйста, попробуйте еще раз.",
|
||||
"follow_orders_banner": "Отслеживайте ваш груз в реальном времени",
|
||||
"order_empty": "У вас пока нет заказов",
|
||||
"deliver_all": "Ваш надежный партнер в мире логистики!"
|
||||
"deliver_all": "Ваш надежный партнер в мире логистики!",
|
||||
"user_already_registered": "Пользователь зарегистрирован!",
|
||||
"alert": "Внимание!",
|
||||
"or": "Или",
|
||||
"register": "Зарегистрироваться",
|
||||
"register_header": "Для входа в личный кабинет",
|
||||
"register_desc": "необходимо зарегистрироваться",
|
||||
"registration_success": "Регистрация прошла успешно!",
|
||||
"dismiss": "OK",
|
||||
"delete": "Удалить аккаунт"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,5 +51,14 @@
|
|||
"error_message": "Näsazlyk ýüze çykdy. Täzeden synanşyp görmegiňizi haýyş edýäris.",
|
||||
"follow_orders_banner": "Ýükiňizi 24 sagadyň dowamynda yzarlamak indi elýeterli",
|
||||
"order_empty": "Siziň entäk sargydyňyz ýok",
|
||||
"deliver_all": "Ýükleri eltip bermekde siziň ynamly hyzmatdaşyňyz!"
|
||||
"deliver_all": "Ýükleri eltip bermekde siziň ynamly hyzmatdaşyňyz!",
|
||||
"user_already_registered": "Ulanyjy hasaba alnan!",
|
||||
"alert": "Üns beriň",
|
||||
"or": "Ýa-da",
|
||||
"register": "Agza bol",
|
||||
"register_header": "Şahsy otaga girmek üçin",
|
||||
"register_desc": "hasaba alynmagyňyzy haýyş edýäris",
|
||||
"registration_success": "Üstünlikli hasaba alyndy!",
|
||||
"dismiss": "OK",
|
||||
"delete": "Hasaby poz"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,18 +14,24 @@ class UserBloc extends Bloc<UserEvent, UserState> {
|
|||
final GetCachedUserUseCase _getCachedUserUseCase;
|
||||
final GetRemoteUserUsecase _getRemoteUserUseCase;
|
||||
final SignInUseCase _signInUseCase;
|
||||
final SignUpUseCase _signUpUseCase;
|
||||
final SignOutUseCase _signOutUseCase;
|
||||
final DeleteAccountUseCase _deleteAccountUseCase;
|
||||
UserBloc(
|
||||
this._signInUseCase,
|
||||
this._signUpUseCase,
|
||||
this._getCachedUserUseCase,
|
||||
this._getRemoteUserUseCase,
|
||||
this._signOutUseCase,
|
||||
this._deleteAccountUseCase,
|
||||
) : super(UserInitial()) {
|
||||
on<SignInUser>(_onSignIn);
|
||||
on<SignUpUser>(_onSignUp);
|
||||
on<CheckUser>(_onCheckUser);
|
||||
on<GetRemoteUser>(_onGetRemoteUser);
|
||||
on<SignOutUser>(_onSignOut);
|
||||
on<GetUser>(_onGetUser);
|
||||
on<DeleteAccount>(_onDeleteAccount);
|
||||
}
|
||||
|
||||
void _onSignIn(SignInUser event, Emitter<UserState> emit) async {
|
||||
|
|
@ -42,6 +48,28 @@ class UserBloc extends Bloc<UserEvent, UserState> {
|
|||
}
|
||||
}
|
||||
|
||||
void _onSignUp(SignUpUser event, Emitter<UserState> emit) async {
|
||||
try {
|
||||
emit(UserLoading());
|
||||
// await Future.delayed(const Duration(seconds: 3));
|
||||
final result = await _signUpUseCase(event.params);
|
||||
result.fold(
|
||||
(failure) => emit(UserLoggedFail(failure)),
|
||||
(code) {
|
||||
if (code == 200) {
|
||||
emit(UserRegistered());
|
||||
} else if (code == 409) {
|
||||
emit(UserAlreadyRegistered());
|
||||
} else {
|
||||
emit(UserLoggedFail(ExceptionFailure()));
|
||||
}
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
emit(UserLoggedFail(ExceptionFailure()));
|
||||
}
|
||||
}
|
||||
|
||||
void _onCheckUser(CheckUser event, Emitter<UserState> emit) async {
|
||||
try {
|
||||
emit(UserLoading());
|
||||
|
|
@ -65,6 +93,25 @@ class UserBloc extends Bloc<UserEvent, UserState> {
|
|||
}
|
||||
}
|
||||
|
||||
void _onDeleteAccount(DeleteAccount event, Emitter<UserState> emit) async {
|
||||
try {
|
||||
emit(DeleteLoading());
|
||||
final result = await _deleteAccountUseCase(NoParams());
|
||||
result.fold(
|
||||
(failure) => emit(_mapFailureToState(failure)),
|
||||
(code) {
|
||||
if (code == 204) {
|
||||
emit(AccountDeleted());
|
||||
} else {
|
||||
emit(UserLoggedFail(ExceptionFailure()));
|
||||
}
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
emit(UserLoggedFail(ExceptionFailure()));
|
||||
}
|
||||
}
|
||||
|
||||
FutureOr<void> _onGetRemoteUser(
|
||||
GetRemoteUser event,
|
||||
Emitter<UserState> emit,
|
||||
|
|
|
|||
|
|
@ -8,6 +8,11 @@ class SignInUser extends UserEvent {
|
|||
SignInUser(this.params);
|
||||
}
|
||||
|
||||
class SignUpUser extends UserEvent {
|
||||
final SignUpParams params;
|
||||
SignUpUser(this.params);
|
||||
}
|
||||
|
||||
class SignOutUser extends UserEvent {}
|
||||
|
||||
class CheckUser extends UserEvent {}
|
||||
|
|
@ -15,3 +20,5 @@ class CheckUser extends UserEvent {}
|
|||
class GetRemoteUser extends UserEvent {}
|
||||
|
||||
class GetUser extends UserEvent {}
|
||||
|
||||
class DeleteAccount extends UserEvent {}
|
||||
|
|
|
|||
|
|
@ -38,3 +38,23 @@ class UserLoggedOut extends UserState {
|
|||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class AccountDeleted extends UserState {
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class UserRegistered extends UserState {
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class UserAlreadyRegistered extends UserState {
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class DeleteLoading extends UserState {
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
const String baseUrl = 'https://192.168.99.64:5001/api';
|
||||
const String imageUrl = 'https://192.168.99.64:5001';
|
||||
// const String baseUrl = 'https://cargo.tpsadvertising.com/api';
|
||||
// const String imageUrl = 'https://cargo.tpsadvertising.com';
|
||||
// const String baseUrl = 'https://192.168.99.64:5001/api';
|
||||
// const String imageUrl = 'https://192.168.99.64:5001';
|
||||
const String baseUrl = 'https://cargo.tpsadvertising.com/api';
|
||||
const String imageUrl = 'https://cargo.tpsadvertising.com';
|
||||
const String defaultApiKey = '';
|
||||
const String defaultSources = '';
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ sealed class AppRouter {
|
|||
static const String splash = '/splash';
|
||||
static const String splash2 = '/splash2';
|
||||
static const String login = '/login';
|
||||
static const String register = '/register';
|
||||
static const String root = '/root';
|
||||
static const String orderDetails = '/order-details';
|
||||
|
||||
|
|
@ -20,6 +21,8 @@ sealed class AppRouter {
|
|||
return MaterialPageRoute(builder: (_) => const Splash2Screen());
|
||||
case login:
|
||||
return MaterialPageRoute(builder: (_) => const LoginScreen());
|
||||
case register:
|
||||
return MaterialPageRoute(builder: (_) => const RegisterScreen());
|
||||
case root:
|
||||
return MaterialPageRoute(builder: (_) => const RootScreen());
|
||||
case orderDetails:
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
import '../../../core/core.dart';
|
||||
|
|
@ -8,6 +9,8 @@ import '../../data.dart';
|
|||
|
||||
abstract class UserRemoteDataSource {
|
||||
Future<String> signIn(SignInParams params);
|
||||
Future<int> signUp(SignUpParams params);
|
||||
Future<int> deleteAccount(String token);
|
||||
Future<User> getUser(String token);
|
||||
Future<void> registerFBToken(String token, String fbToken);
|
||||
}
|
||||
|
|
@ -41,6 +44,23 @@ class UserRemoteDataSourceImpl implements UserRemoteDataSource {
|
|||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<int> signUp(SignUpParams params) async {
|
||||
final response = await client.post(
|
||||
Uri.parse('$baseUrl/Client/Register'),
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
'accept': '*/*',
|
||||
},
|
||||
body: {
|
||||
'username': params.username.trim(),
|
||||
'password': params.password,
|
||||
},
|
||||
);
|
||||
|
||||
return response.statusCode;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<User> getUser(String token) async {
|
||||
final response = await client.get(
|
||||
|
|
@ -62,7 +82,8 @@ class UserRemoteDataSourceImpl implements UserRemoteDataSource {
|
|||
|
||||
@override
|
||||
Future<void> registerFBToken(String token, String fbToken) async {
|
||||
final response = await client.post(
|
||||
/* final response = */
|
||||
await client.post(
|
||||
Uri.parse('$baseUrl/Client/FirebaseToken?token=$fbToken'),
|
||||
headers: {
|
||||
'accept': '*/*',
|
||||
|
|
@ -75,4 +96,20 @@ class UserRemoteDataSourceImpl implements UserRemoteDataSource {
|
|||
throw ServerException();
|
||||
} */
|
||||
}
|
||||
|
||||
@override
|
||||
Future<int> deleteAccount(String token) async {
|
||||
final response = await client.delete(
|
||||
Uri.parse('$baseUrl/Client/DeleteAccount'),
|
||||
headers: {
|
||||
'accept': '*/*',
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': 'Bearer $token',
|
||||
},
|
||||
);
|
||||
|
||||
debugPrint(response.body);
|
||||
|
||||
return response.statusCode;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,22 @@ class UserRepositoryImpl implements UserRepository {
|
|||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Either<Failure, int>> signUp(params) async {
|
||||
if (await networkInfo.isConnected) {
|
||||
try {
|
||||
/// register
|
||||
final code = await remoteDataSource.signUp(params);
|
||||
|
||||
return Right(code);
|
||||
} on Failure catch (failure) {
|
||||
return Left(failure);
|
||||
}
|
||||
} else {
|
||||
return Left(NetworkFailure());
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Either<Failure, User>> getCachedUser() async {
|
||||
try {
|
||||
|
|
@ -62,6 +78,22 @@ class UserRepositoryImpl implements UserRepository {
|
|||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Either<Failure, int>> deleteAccount() async {
|
||||
try {
|
||||
final String token = await localDataSource.getToken();
|
||||
final code = await remoteDataSource.deleteAccount(token);
|
||||
if (code == 204) {
|
||||
await localDataSource.clearCache();
|
||||
}
|
||||
return Right(code);
|
||||
} on CacheFailure {
|
||||
return Left(CacheFailure());
|
||||
} catch (error) {
|
||||
return Left(ExceptionFailure());
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Either<Failure, User>> getRemoteUser() async {
|
||||
if (!await networkInfo.isConnected) {
|
||||
|
|
|
|||
|
|
@ -7,10 +7,12 @@ import 'di.dart';
|
|||
|
||||
void registerUserFeature() {
|
||||
// User BLoC and Use Cases
|
||||
sl.registerFactory(() => UserBloc(sl(), sl(), sl(), sl()));
|
||||
sl.registerFactory(() => UserBloc(sl(), sl(), sl(), sl(), sl(), sl()));
|
||||
sl.registerLazySingleton(() => GetCachedUserUseCase(sl()));
|
||||
sl.registerLazySingleton(() => SignInUseCase(sl()));
|
||||
sl.registerLazySingleton(() => SignUpUseCase(sl()));
|
||||
sl.registerLazySingleton(() => SignOutUseCase(sl()));
|
||||
sl.registerLazySingleton(() => DeleteAccountUseCase(sl()));
|
||||
sl.registerLazySingleton(() => GetRemoteUserUsecase(sl()));
|
||||
|
||||
// User Repository and Data Sources
|
||||
|
|
|
|||
|
|
@ -5,7 +5,9 @@ import '../domain.dart';
|
|||
|
||||
abstract class UserRepository {
|
||||
Future<Either<Failure, String>> signIn(SignInParams params);
|
||||
Future<Either<Failure, int>> signUp(SignUpParams params);
|
||||
Future<Either<Failure, NoParams>> signOut();
|
||||
Future<Either<Failure, int>> deleteAccount();
|
||||
Future<Either<Failure, User>> getCachedUser();
|
||||
Future<Either<Failure, User>> getRemoteUser();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
import 'package:dartz/dartz.dart';
|
||||
|
||||
import '../../../core/core.dart';
|
||||
import '../../domain.dart';
|
||||
|
||||
class DeleteAccountUseCase implements UseCase<int, NoParams> {
|
||||
final UserRepository repository;
|
||||
DeleteAccountUseCase(this.repository);
|
||||
|
||||
@override
|
||||
Future<Either<Failure, int>> call(NoParams params) async {
|
||||
return await repository.deleteAccount();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,27 +1,27 @@
|
|||
// import 'package:dartz/dartz.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
|
||||
// import '../../../core/core.dart';
|
||||
// import '../../domain.dart';
|
||||
import '../../../core/core.dart';
|
||||
import '../../domain.dart';
|
||||
|
||||
// class SignUpUseCase implements UseCase<User, SignUpParams> {
|
||||
// final UserRepository repository;
|
||||
// SignUpUseCase(this.repository);
|
||||
class SignUpUseCase implements UseCase<int, SignUpParams> {
|
||||
final UserRepository repository;
|
||||
SignUpUseCase(this.repository);
|
||||
|
||||
// @override
|
||||
// Future<Either<Failure, User>> call(SignUpParams params) async {
|
||||
// return await repository.signUp(params);
|
||||
// }
|
||||
// }
|
||||
@override
|
||||
Future<Either<Failure, int>> call(SignUpParams params) async {
|
||||
return await repository.signUp(params);
|
||||
}
|
||||
}
|
||||
|
||||
// class SignUpParams {
|
||||
// final String firstName;
|
||||
// final String lastName;
|
||||
// final String email;
|
||||
// final String password;
|
||||
// const SignUpParams({
|
||||
// required this.firstName,
|
||||
// required this.lastName,
|
||||
// required this.email,
|
||||
// required this.password,
|
||||
// });
|
||||
// }
|
||||
class SignUpParams {
|
||||
// final String firstName;
|
||||
// final String lastName;
|
||||
final String username;
|
||||
final String password;
|
||||
const SignUpParams({
|
||||
// required this.firstName,
|
||||
// required this.lastName,
|
||||
required this.username,
|
||||
required this.password,
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,4 +2,5 @@ export 'get_cached_user_usecase.dart';
|
|||
export 'sign_in_usecase.dart';
|
||||
export 'sign_out_usecase.dart';
|
||||
export 'sign_up_usecase.dart';
|
||||
export 'delete_account_usecase.dart';
|
||||
export 'get_remote_user_usecase.dart';
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import '../../configs/configs.dart';
|
|||
import '../../core/core.dart';
|
||||
import '../../domain/domain.dart';
|
||||
import '../widgets/widgets.dart';
|
||||
import 'dart:io' show Platform;
|
||||
|
||||
class LoginScreen extends StatefulWidget {
|
||||
const LoginScreen({super.key});
|
||||
|
|
@ -100,7 +101,7 @@ class _LoginScreenState extends State<LoginScreen> {
|
|||
|
||||
/// form part
|
||||
SizedBox(
|
||||
height: AppDimensions.normalize(165),
|
||||
height: AppDimensions.normalize(190),
|
||||
child: Stack(
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
|
|
@ -232,6 +233,56 @@ class _LoginScreenState extends State<LoginScreen> {
|
|||
);
|
||||
},
|
||||
),
|
||||
|
||||
if (Platform.isAndroid)
|
||||
Align(
|
||||
alignment: Alignment.center,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
/// spacer
|
||||
Space.yf(),
|
||||
Text(
|
||||
'or'.tr(),
|
||||
style: AppText.h3,
|
||||
),
|
||||
Space.yf(),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 22),
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
color: AppColors.primary, // Border color
|
||||
width: 1.0, // Border width
|
||||
),
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
child: TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor: AppColors.primary,
|
||||
padding: EdgeInsets.zero,
|
||||
textStyle: const TextStyle(
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
debugPrint('register');
|
||||
Navigator.of(context).pushNamedAndRemoveUntil(
|
||||
AppRouter.register,
|
||||
(route) => false,
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
'register'.tr(),
|
||||
style: AppText.b1b,
|
||||
),
|
||||
),
|
||||
),
|
||||
Space.yf(0.30),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
|||
backgroundColor: AppColors.surface,
|
||||
body: BlocConsumer<UserBloc, UserState>(
|
||||
listener: (context, state) {
|
||||
if (state is UserLoggedOut || state is UserLoggedFail) {
|
||||
if (state is UserLoggedOut || state is UserLoggedFail || state is AccountDeleted) {
|
||||
_navigateToLoginScreen(context);
|
||||
}
|
||||
},
|
||||
|
|
@ -121,11 +121,42 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
|||
child: Text(
|
||||
'logout'.tr(),
|
||||
style: AppText.b1!.copyWith(
|
||||
color: Colors.red,
|
||||
color: AppColors.primary,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
///gap
|
||||
Space.yf(3),
|
||||
|
||||
BlocBuilder<UserBloc, UserState>(
|
||||
builder: (context, state) {
|
||||
if (state is DeleteLoading) {
|
||||
// Show loader when the state is DeleteLoading
|
||||
return const Align(
|
||||
alignment: Alignment.center,
|
||||
child: CircularProgressIndicator(), // Loader
|
||||
);
|
||||
} else {
|
||||
// Show the delete button in other states
|
||||
return Align(
|
||||
alignment: Alignment.center,
|
||||
child: TextButton(
|
||||
onPressed: () {
|
||||
context.read<UserBloc>().add(DeleteAccount());
|
||||
},
|
||||
child: Text(
|
||||
'delete'.tr(),
|
||||
style: AppText.b1!.copyWith(
|
||||
color: Colors.red,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,314 @@
|
|||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import '../../application/user_bloc/user_bloc.dart';
|
||||
import '../../configs/configs.dart';
|
||||
import '../../core/core.dart';
|
||||
import '../../domain/domain.dart';
|
||||
import '../widgets/widgets.dart';
|
||||
import 'dart:io' show Platform;
|
||||
|
||||
class RegisterScreen extends StatefulWidget {
|
||||
const RegisterScreen({super.key});
|
||||
|
||||
@override
|
||||
State<RegisterScreen> createState() => _RegisterScreenState();
|
||||
}
|
||||
|
||||
class _RegisterScreenState extends State<RegisterScreen> {
|
||||
final TextEditingController _userNameController = TextEditingController();
|
||||
final TextEditingController _passwordController = TextEditingController();
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
bool _obscureText = true;
|
||||
|
||||
void _nextScreen() {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('registration_success'.tr()),
|
||||
backgroundColor: Colors.green,
|
||||
duration: const Duration(seconds: 2),
|
||||
),
|
||||
);
|
||||
|
||||
Navigator.of(context).pushNamedAndRemoveUntil(
|
||||
AppRouter.login,
|
||||
(route) => false,
|
||||
);
|
||||
}
|
||||
|
||||
void _onEyeTapped() {
|
||||
setState(() {
|
||||
_obscureText = !_obscureText;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_userNameController.dispose();
|
||||
_passwordController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
App.init(context);
|
||||
return Scaffold(
|
||||
body: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
/// image part
|
||||
Container(
|
||||
height: AppDimensions.normalize(155),
|
||||
color: AppColors.primary,
|
||||
child: SingleChildScrollView(
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.only(top: 20, bottom: 20),
|
||||
child: Column(
|
||||
children: [
|
||||
// SvgPicture.asset(
|
||||
// AppAssets.logo,
|
||||
// height: AppDimensions.normalize(30),
|
||||
// ),
|
||||
Space.yf(4),
|
||||
|
||||
Image.asset(
|
||||
AppAssets.logoLogin,
|
||||
),
|
||||
Space.yf(0.50),
|
||||
Text(
|
||||
appTitle,
|
||||
style: AppText.h1b?.copyWith(
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
Space.yf(0.30),
|
||||
Text(
|
||||
'deliver_all'.tr(),
|
||||
style: AppText.b1?.copyWith(
|
||||
color: AppColors.yellow,
|
||||
),
|
||||
),
|
||||
Image.asset(
|
||||
AppAssets.trucksPng,
|
||||
height: AppDimensions.normalize(52),
|
||||
width: double.infinity,
|
||||
fit: BoxFit.fill,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
/// form part
|
||||
SizedBox(
|
||||
height: AppDimensions.normalize(190),
|
||||
child: Stack(
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
Positioned(
|
||||
top: -20,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(16),
|
||||
topRight: Radius.circular(16),
|
||||
),
|
||||
),
|
||||
child: Padding(
|
||||
padding: Space.hf().copyWith(top: 30),
|
||||
child: Form(
|
||||
key: _formKey,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'register_header'.tr(),
|
||||
style: const TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
|
||||
Space.yf(0.5),
|
||||
|
||||
Text(
|
||||
'register_desc'.tr(),
|
||||
style: const TextStyle(
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
|
||||
/// gap
|
||||
Space.yf(),
|
||||
|
||||
/// username field
|
||||
Text('login'.tr()),
|
||||
Space.y!,
|
||||
TextFormField(
|
||||
controller: _userNameController,
|
||||
decoration: InputDecoration(
|
||||
hintText: 'login_hint'.tr(),
|
||||
prefixIcon: const Icon(Icons.person_outline),
|
||||
border: const OutlineInputBorder(),
|
||||
),
|
||||
validator: (val) => FormValidator.validateField(val),
|
||||
),
|
||||
|
||||
/// gap
|
||||
Space.yf(),
|
||||
|
||||
/// password field
|
||||
Text('password'.tr()),
|
||||
Space.y!,
|
||||
TextFormField(
|
||||
controller: _passwordController,
|
||||
obscureText: _obscureText,
|
||||
decoration: InputDecoration(
|
||||
hintText: 'password_hint'.tr(),
|
||||
prefixIcon: const Icon(Icons.lock_outline),
|
||||
suffixIcon: GestureDetector(
|
||||
onTap: _onEyeTapped,
|
||||
child: _obscureText
|
||||
? const Icon(Icons.visibility_off)
|
||||
: const Icon(
|
||||
Icons.visibility,
|
||||
),
|
||||
),
|
||||
border: const OutlineInputBorder(),
|
||||
),
|
||||
validator: (val) => FormValidator.validateField(val),
|
||||
),
|
||||
|
||||
/// gap
|
||||
Space.yf(),
|
||||
|
||||
BlocConsumer<UserBloc, UserState>(
|
||||
listener: (context, state) {
|
||||
if (state is UserRegistered) {
|
||||
_nextScreen();
|
||||
} else if (state is UserAlreadyRegistered) {
|
||||
showErrorDialog(
|
||||
context: context,
|
||||
header: 'alert'.tr(),
|
||||
body: 'user_already_registered'.tr(),
|
||||
);
|
||||
} else if (state is UserLoggedFail) {
|
||||
if (state.failure is CredentialFailure) {
|
||||
showErrorDialog(
|
||||
context: context,
|
||||
header: 'credentials_validation_header'.tr(),
|
||||
body: 'credentials_validation_body'.tr(),
|
||||
);
|
||||
} else {
|
||||
showAuthErrorDialog(context);
|
||||
}
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
if (state is UserLoading) {
|
||||
return const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
);
|
||||
}
|
||||
return SizedBox(
|
||||
width: double.infinity,
|
||||
child: AppButton(
|
||||
textColor: Colors.white,
|
||||
btnColor: AppColors.primary,
|
||||
onPressed: () {
|
||||
if (_formKey.currentState!.validate()) {
|
||||
Keyboard.hide(context);
|
||||
|
||||
/// sign in
|
||||
context.read<UserBloc>().add(
|
||||
SignUpUser(
|
||||
SignUpParams(
|
||||
username: _userNameController.text,
|
||||
password: _passwordController.text,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
text: 'register'.tr(),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
if (Platform.isAndroid)
|
||||
Align(
|
||||
alignment: Alignment.center,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
/// spacer
|
||||
Space.yf(),
|
||||
Text(
|
||||
'or'.tr(),
|
||||
style: AppText.h3,
|
||||
),
|
||||
Space.yf(),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 22),
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
color: AppColors.primary, // Border color
|
||||
width: 1.0, // Border width
|
||||
),
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
child: TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor: AppColors.primary,
|
||||
padding: EdgeInsets.zero,
|
||||
textStyle: const TextStyle(
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
debugPrint('login');
|
||||
Navigator.of(context).pushNamedAndRemoveUntil(
|
||||
AppRouter.login,
|
||||
(route) => false,
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
'start_tracking'.tr(),
|
||||
style: AppText.b1b,
|
||||
),
|
||||
),
|
||||
),
|
||||
Space.yf(0.30),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -7,3 +7,4 @@ export 'root.dart';
|
|||
export 'splash.dart';
|
||||
export 'splash2.dart';
|
||||
export 'image_full.dart';
|
||||
export 'register.dart';
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../configs/configs.dart';
|
||||
|
|
@ -7,7 +8,7 @@ Future<void> showErrorDialog({
|
|||
required BuildContext context,
|
||||
required String header,
|
||||
required String body,
|
||||
String dismissButtonText = 'Dismiss',
|
||||
String dismissButtonText = 'dismiss',
|
||||
VoidCallback? onDismiss,
|
||||
}) async {
|
||||
return showDialog(
|
||||
|
|
@ -52,7 +53,7 @@ Future<void> showErrorDialog({
|
|||
}
|
||||
},
|
||||
child: Text(
|
||||
dismissButtonText,
|
||||
dismissButtonText.tr(),
|
||||
style: AppText.h3b?.copyWith(
|
||||
color: AppColors.primary,
|
||||
),
|
||||
|
|
|
|||
Loading…
Reference in New Issue