You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

200 lines
6.9KB

  1. import 'package:farm_tpf/authentication/authentication.dart';
  2. import 'package:farm_tpf/data/repository/authentication_repository.dart';
  3. import 'package:farm_tpf/presentation/custom_widgets/widget_loading.dart';
  4. import 'package:farm_tpf/presentation/custom_widgets/widget_utils.dart';
  5. import 'package:farm_tpf/presentation/screens/forgot_password/sc_forgot_password.dart';
  6. import 'package:farm_tpf/presentation/screens/login/bloc/login_bloc.dart';
  7. import 'package:farm_tpf/utils/const_color.dart';
  8. import 'package:flutter/material.dart';
  9. import 'package:formz/formz.dart';
  10. import 'package:flutter_bloc/flutter_bloc.dart';
  11. class LoginForm extends StatelessWidget {
  12. AuthenticationBloc _authenticationBloc;
  13. FocusNode _usernameFocus = FocusNode();
  14. FocusNode _passwordFocus = FocusNode();
  15. @override
  16. Widget build(BuildContext context) {
  17. _authenticationBloc = BlocProvider.of<AuthenticationBloc>(context);
  18. return BlocListener<LoginBloc, LoginState>(
  19. listener: (context, state) {
  20. if (state.status.isSubmissionFailure) {
  21. LoadingDialog.hideLoadingDialog(context);
  22. Utils.showSnackBarError(
  23. message: 'Tài khoản hoặc mật khẩu không đúng.');
  24. }
  25. if (state.status.isSubmissionSuccess) {
  26. LoadingDialog.hideLoadingDialog(context);
  27. _authenticationBloc.add(
  28. AuthenticationStatusChanged(AuthenticationStatus.authenticated));
  29. }
  30. if (state.status.isSubmissionInProgress) {
  31. LoadingDialog.showLoadingDialog(context);
  32. }
  33. },
  34. child: Align(
  35. child: Column(
  36. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  37. mainAxisSize: MainAxisSize.min,
  38. children: [
  39. _UsernameInput(
  40. usernameFocus: _usernameFocus, nextFocus: _passwordFocus),
  41. const Padding(padding: EdgeInsets.all(12)),
  42. _PasswordInput(
  43. passwordFocus: _passwordFocus,
  44. ),
  45. const Padding(padding: EdgeInsets.all(16)),
  46. _LoginButton(),
  47. const Padding(padding: EdgeInsets.all(6)),
  48. _FogotPasswordButton(),
  49. ],
  50. ),
  51. ),
  52. );
  53. }
  54. }
  55. class _FogotPasswordButton extends StatelessWidget {
  56. @override
  57. Widget build(BuildContext context) {
  58. return Align(
  59. alignment: Alignment.centerRight,
  60. child: FlatButton(
  61. child: Text(
  62. 'Quên mật khẩu ?',
  63. ),
  64. onPressed: () {
  65. Navigator.of(context).push(
  66. MaterialPageRoute(builder: (_) => ForgotPasswordScreen()));
  67. }));
  68. }
  69. }
  70. class _UsernameInput extends StatelessWidget {
  71. final FocusNode usernameFocus;
  72. final FocusNode nextFocus;
  73. _UsernameInput({@required this.usernameFocus, @required this.nextFocus});
  74. @override
  75. Widget build(BuildContext context) {
  76. return BlocBuilder<LoginBloc, LoginState>(
  77. buildWhen: (previous, current) => previous.username != current.username,
  78. builder: (context, state) {
  79. return Container(
  80. height: 50,
  81. padding: EdgeInsets.symmetric(horizontal: 17),
  82. decoration: BoxDecoration(
  83. shape: BoxShape.rectangle,
  84. borderRadius: BorderRadius.circular(10),
  85. color: COLOR_CONST.GRAY7),
  86. child: Center(
  87. child: TextFormField(
  88. focusNode: usernameFocus,
  89. textInputAction: TextInputAction.next,
  90. onChanged: (username) => context
  91. .bloc<LoginBloc>()
  92. .add(LoginUsernameChanged(username)),
  93. autovalidate: true,
  94. validator: (_) {
  95. return state.username.invalid
  96. ? 'Vui lòng nhập tài khoản'
  97. : null;
  98. },
  99. onFieldSubmitted: (_) {
  100. usernameFocus.unfocus();
  101. FocusScope.of(context).requestFocus(nextFocus);
  102. },
  103. maxLines: 1,
  104. keyboardType: TextInputType.text,
  105. obscureText: false,
  106. textAlign: TextAlign.left,
  107. decoration: InputDecoration.collapsed(
  108. hintText: 'Tài khoản',
  109. ),
  110. ),
  111. ));
  112. },
  113. );
  114. }
  115. }
  116. class _PasswordInput extends StatelessWidget {
  117. final FocusNode passwordFocus;
  118. _PasswordInput({this.passwordFocus});
  119. @override
  120. Widget build(BuildContext context) {
  121. return BlocBuilder<LoginBloc, LoginState>(
  122. buildWhen: (previous, current) => previous.password != current.password,
  123. builder: (context, state) {
  124. return Container(
  125. height: 50,
  126. padding: EdgeInsets.symmetric(horizontal: 17),
  127. decoration: BoxDecoration(
  128. shape: BoxShape.rectangle,
  129. borderRadius: BorderRadius.circular(10),
  130. color: COLOR_CONST.GRAY7),
  131. child: Center(
  132. child: TextFormField(
  133. focusNode: passwordFocus,
  134. onChanged: (password) => context
  135. .bloc<LoginBloc>()
  136. .add(LoginPasswordChanged(password)),
  137. autovalidate: true,
  138. validator: (_) {
  139. return state.password.invalid
  140. ? 'Vui lòng nhập mật khẩu'
  141. : null;
  142. },
  143. onFieldSubmitted: (_) {
  144. passwordFocus.unfocus();
  145. if (state.status.isValidated) {
  146. context.bloc<LoginBloc>().add(const LoginSubmitted());
  147. }
  148. },
  149. maxLines: 1,
  150. keyboardType: TextInputType.text,
  151. obscureText: true,
  152. textAlign: TextAlign.left,
  153. decoration: InputDecoration.collapsed(
  154. hintText: 'Mật khẩu',
  155. ),
  156. ),
  157. ));
  158. },
  159. );
  160. }
  161. }
  162. class _LoginButton extends StatelessWidget {
  163. @override
  164. Widget build(BuildContext context) {
  165. return BlocBuilder<LoginBloc, LoginState>(
  166. buildWhen: (previous, current) => previous.status != current.status,
  167. builder: (context, state) {
  168. return SizedBox(
  169. width: double.infinity,
  170. height: 55,
  171. child: FlatButton(
  172. onPressed: () {
  173. if (state.status.isValidated) {
  174. context.bloc<LoginBloc>().add(const LoginSubmitted());
  175. }
  176. },
  177. color: state.status.isValidated
  178. ? COLOR_CONST.DEFAULT
  179. : COLOR_CONST.GRAY1_50,
  180. shape: RoundedRectangleBorder(
  181. borderRadius: new BorderRadius.circular(7.0),
  182. ),
  183. child: Text(
  184. 'Đăng nhập'.toUpperCase(),
  185. style: TextStyle(
  186. fontWeight: FontWeight.bold, color: COLOR_CONST.WHITE),
  187. ),
  188. ),
  189. );
  190. },
  191. );
  192. }
  193. }