forked from eatvio/eatvio_app
Auth screen layout
This commit is contained in:
@@ -100,6 +100,11 @@ final Map<String, String> ru = {
|
||||
"pressure_empty": "Все показатели давления обязательны к заполнению",
|
||||
"pressure_is_not_a_number": "Все показатели давления должны быть числами",
|
||||
|
||||
// Authorization
|
||||
"no_account": "У меня нет аккаунта",
|
||||
"authentificate": "Войти",
|
||||
"user_authorization": "Аутентификация",
|
||||
|
||||
// Личный кабинет Screen
|
||||
"Dmitry_Koval": "Дмитрий Коваль", "done": "Готово", "exit": "Выйти",
|
||||
"my_blog": "Мой блог", "lbl_01_04_21": "01.04.21", "lbl_01_05_21": "01.05.21",
|
||||
|
||||
139
lib/presentation/auth/auth_screen/auth_screen.dart
Normal file
139
lib/presentation/auth/auth_screen/auth_screen.dart
Normal file
@@ -0,0 +1,139 @@
|
||||
import 'bloc/auth_bloc.dart';
|
||||
import 'models/auth_model.dart';
|
||||
import 'package:eatvio_app/core/app_export.dart';
|
||||
import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart';
|
||||
import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart';
|
||||
import 'package:validators/validators.dart';
|
||||
import 'package:eatvio_app/widgets/next_step_button.dart';
|
||||
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class AuthScreen extends StatelessWidget {
|
||||
static Widget builder(BuildContext context) {
|
||||
return BlocProvider<AuthBloc>(
|
||||
create: (context) => AuthBloc(
|
||||
AuthState(
|
||||
authModelObj: AuthModel(),
|
||||
),
|
||||
)..add(AuthInitialEvent()),
|
||||
child: AuthScreen(),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
mediaQueryData = MediaQuery.of(context);
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
appBar: _buildAppBar(context),
|
||||
body: Container(
|
||||
width: double.maxFinite,
|
||||
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
|
||||
child: Column(children: [
|
||||
SizedBox(height: 39.v),
|
||||
Text("user_authorization".tr,
|
||||
style: theme.textTheme.headlineSmall),
|
||||
SizedBox(height: 60.v),
|
||||
Text("email".tr, style: theme.textTheme.bodyLarge),
|
||||
SizedBox(height: 3.v),
|
||||
BlocSelector<AuthBloc, AuthState, TextEditingController?>(
|
||||
selector: (state) => state.emailController,
|
||||
builder: (context, emailController) {
|
||||
return CustomTextFormField(
|
||||
controller: emailController,
|
||||
textInputAction: TextInputAction.done);
|
||||
}),
|
||||
SizedBox(height: 22.v),
|
||||
Text("password".tr, style: theme.textTheme.bodyLarge),
|
||||
SizedBox(height: 5.v),
|
||||
BlocSelector<AuthBloc, AuthState, TextEditingController?>(
|
||||
selector: (state) => state.passwordController,
|
||||
builder: (context, passwordController) {
|
||||
return CustomTextFormField(
|
||||
obscureText: true,
|
||||
controller: passwordController,
|
||||
);
|
||||
}),
|
||||
Spacer(),
|
||||
NextStepButton(
|
||||
text: "no_account".tr.toUpperCase(),
|
||||
margin:
|
||||
EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v),
|
||||
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
|
||||
onPressed: () {
|
||||
Navigator.pushNamed(
|
||||
context, AppRoutes.languageSelectScreen);
|
||||
}),
|
||||
BlocBuilder<AuthBloc, AuthState>(builder: (context, state) {
|
||||
return NextStepButton(
|
||||
text: "authentificate".tr.toUpperCase(),
|
||||
margin:
|
||||
EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v),
|
||||
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
|
||||
onPressed: () {
|
||||
List<String> errors = validateFields(
|
||||
state.emailController!.text,
|
||||
state.passwordController!.text);
|
||||
if (errors.isEmpty) {
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.myProfile,
|
||||
);
|
||||
} else {
|
||||
String errorMessage = '';
|
||||
|
||||
for (var error in errors) {
|
||||
errorMessage += error + '\n\n';
|
||||
}
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
title: Text('Ошибка'),
|
||||
content: Text(errorMessage),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Text('OK'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
});
|
||||
}),
|
||||
])));
|
||||
}
|
||||
|
||||
/// Section Widget
|
||||
PreferredSizeWidget _buildAppBar(BuildContext context) {
|
||||
return CustomAppBar(
|
||||
leadingWidth: 29.h,
|
||||
centerTitle: true,
|
||||
title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio));
|
||||
}
|
||||
|
||||
List<String> validateFields(String email, String password) {
|
||||
List<String> errors = [];
|
||||
|
||||
if (!isEmail(email)) {
|
||||
errors.add('email_invalid'.tr);
|
||||
}
|
||||
|
||||
if (email.isEmpty) {
|
||||
errors.add('email_empty'.tr);
|
||||
}
|
||||
|
||||
if (password.isEmpty) {
|
||||
errors.add('password_empty'.tr);
|
||||
}
|
||||
|
||||
if (password.length < 6) {
|
||||
errors.add('password_short'.tr);
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
22
lib/presentation/auth/auth_screen/bloc/auth_bloc.dart
Normal file
22
lib/presentation/auth/auth_screen/bloc/auth_bloc.dart
Normal file
@@ -0,0 +1,22 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import '/core/app_export.dart';
|
||||
import 'package:eatvio_app/presentation/auth/auth_screen/models/auth_model.dart';
|
||||
part 'auth_event.dart';
|
||||
part 'auth_state.dart';
|
||||
|
||||
/// A bloc that manages the state of a Auth according to the event that is dispatched to it.
|
||||
class AuthBloc extends Bloc<AuthEvent, AuthState> {
|
||||
AuthBloc(AuthState initialState) : super(initialState) {
|
||||
on<AuthInitialEvent>(_onInitialize);
|
||||
}
|
||||
|
||||
_onInitialize(
|
||||
AuthInitialEvent event,
|
||||
Emitter<AuthState> emit,
|
||||
) async {
|
||||
emit(state.copyWith(
|
||||
emailController: TextEditingController(),
|
||||
passwordController: TextEditingController()));
|
||||
}
|
||||
}
|
||||
16
lib/presentation/auth/auth_screen/bloc/auth_event.dart
Normal file
16
lib/presentation/auth/auth_screen/bloc/auth_event.dart
Normal file
@@ -0,0 +1,16 @@
|
||||
// ignore_for_file: must_be_immutable
|
||||
|
||||
part of 'auth_bloc.dart';
|
||||
|
||||
/// Abstract class for all events that can be dispatched from the
|
||||
///Credentials widget.
|
||||
///
|
||||
/// Events must be immutable and implement the [Equatable] interface.
|
||||
@immutable
|
||||
abstract class AuthEvent extends Equatable {}
|
||||
|
||||
/// Event that is dispatched when the Credentials widget is first created.
|
||||
class AuthInitialEvent extends AuthEvent {
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
36
lib/presentation/auth/auth_screen/bloc/auth_state.dart
Normal file
36
lib/presentation/auth/auth_screen/bloc/auth_state.dart
Normal file
@@ -0,0 +1,36 @@
|
||||
// ignore_for_file: must_be_immutable
|
||||
|
||||
part of 'auth_bloc.dart';
|
||||
|
||||
/// Represents the state of Auth in the application.
|
||||
class AuthState extends Equatable {
|
||||
AuthState({
|
||||
this.emailController,
|
||||
this.passwordController,
|
||||
this.authModelObj,
|
||||
});
|
||||
|
||||
TextEditingController? emailController;
|
||||
|
||||
TextEditingController? passwordController;
|
||||
|
||||
AuthModel? authModelObj;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
emailController,
|
||||
passwordController,
|
||||
authModelObj,
|
||||
];
|
||||
AuthState copyWith({
|
||||
TextEditingController? emailController,
|
||||
TextEditingController? passwordController,
|
||||
AuthModel? authModelObj,
|
||||
}) {
|
||||
return AuthState(
|
||||
emailController: emailController ?? this.emailController,
|
||||
passwordController: passwordController ?? this.passwordController,
|
||||
authModelObj: authModelObj ?? this.authModelObj,
|
||||
);
|
||||
}
|
||||
}
|
||||
16
lib/presentation/auth/auth_screen/models/auth_model.dart
Normal file
16
lib/presentation/auth/auth_screen/models/auth_model.dart
Normal file
@@ -0,0 +1,16 @@
|
||||
// ignore_for_file: must_be_immutable
|
||||
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
/// This class defines the variables used in the [auth_screen],
|
||||
/// and is typically used to hold data that is passed between different parts of the application.
|
||||
class AuthModel extends Equatable {
|
||||
AuthModel();
|
||||
|
||||
AuthModel copyWith() {
|
||||
return AuthModel();
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
@@ -80,6 +80,10 @@ class AdditionalInformationScreen extends StatelessWidget {
|
||||
final token = json.decode(response.body)['token'];
|
||||
box.put('token', token);
|
||||
print('token: ${box.get('token')}');
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.myProfile,
|
||||
);
|
||||
});
|
||||
}),
|
||||
]))));
|
||||
|
||||
@@ -130,6 +130,12 @@ class _AppNavigationScreenState extends State<AppNavigationScreen> {
|
||||
onTapScreenTitle: () => onTapScreenTitle(
|
||||
AppRoutes.languageSelectScreen),
|
||||
),
|
||||
_buildScreenTitle(
|
||||
context,
|
||||
screenTitle: "auth".tr,
|
||||
onTapScreenTitle: () =>
|
||||
onTapScreenTitle(AppRoutes.authScreen),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -17,7 +17,7 @@ class SplashBloc extends Bloc<SplashEvent, SplashState> {
|
||||
) async {
|
||||
Future.delayed(const Duration(milliseconds: 3000), () {
|
||||
NavigatorService.popAndPushNamed(
|
||||
AppRoutes.languageSelectScreen,
|
||||
AppRoutes.authScreen,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import 'package:eatvio_app/presentation/registration/height_screen/height_screen
|
||||
import 'package:eatvio_app/presentation/registration/credentials_screen/credentials_screen.dart';
|
||||
import 'package:eatvio_app/presentation/registration/name_screen/name_screen.dart';
|
||||
import 'package:eatvio_app/presentation/registration/app_navigation_screen/app_navigation_screen.dart';
|
||||
import 'package:eatvio_app/presentation/auth/auth_screen/auth_screen.dart';
|
||||
import 'package:eatvio_app/presentation/profile/my_profile_screen/my_profile_screen.dart';
|
||||
|
||||
class AppRoutes {
|
||||
@@ -58,6 +59,8 @@ class AppRoutes {
|
||||
|
||||
static const String appNavigationScreen = '/app_navigation_screen';
|
||||
|
||||
static const String authScreen = '/auth_screen';
|
||||
|
||||
static const String initialRoute = '/initialRoute';
|
||||
|
||||
//PROFILE
|
||||
@@ -74,6 +77,7 @@ class AppRoutes {
|
||||
allergiesScreen: AllergiesScreen.builder,
|
||||
medicineIntakeScreen: MedicineIntakeScreen.builder,
|
||||
splashScreen: SplashScreen.builder,
|
||||
authScreen: AuthScreen.builder,
|
||||
genderScreen: GenderScreen.builder,
|
||||
bloodPressureScreen: BloodPressureScreen.builder,
|
||||
favoriteSportsScreen: FavoriteSportsScreen.builder,
|
||||
|
||||
Reference in New Issue
Block a user