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.

210 lines
7.2KB

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