forked from eatvio/eatvio_app
Auth screen layout
This commit is contained in:
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 => [];
|
||||
}
|
||||
Reference in New Issue
Block a user