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.

234 lines
7.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/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. _registerButton()
  60. ],
  61. ),
  62. ),
  63. );
  64. }
  65. }
  66. class _FogotPasswordButton extends StatelessWidget {
  67. @override
  68. Widget build(BuildContext context) {
  69. return Align(
  70. alignment: Alignment.centerRight,
  71. child: FlatButton(
  72. child: Text(
  73. 'Quên mật khẩu ?',
  74. ),
  75. onPressed: () {
  76. Navigator.of(context).push(
  77. MaterialPageRoute(builder: (_) => ForgotPasswordScreen()));
  78. }));
  79. }
  80. }
  81. Widget _registerButton() {
  82. return Align(
  83. alignment: Alignment.bottomCenter,
  84. child: FlatButton(
  85. child: RichText(
  86. text: new TextSpan(
  87. style: new TextStyle(
  88. fontSize: 14.0,
  89. color: Colors.black,
  90. ),
  91. children: <TextSpan>[
  92. new TextSpan(text: 'Không có tài khoản? '),
  93. new TextSpan(
  94. text: 'Tạo mới.',
  95. style: new TextStyle(
  96. fontWeight: FontWeight.bold,
  97. color: COLOR_CONST.DEFAULT)),
  98. ],
  99. ),
  100. ),
  101. onPressed: () {}));
  102. }
  103. class _UsernameInput extends StatelessWidget {
  104. final FocusNode usernameFocus;
  105. final FocusNode nextFocus;
  106. _UsernameInput({@required this.usernameFocus, @required this.nextFocus});
  107. @override
  108. Widget build(BuildContext context) {
  109. return BlocBuilder<LoginBloc, LoginState>(
  110. buildWhen: (previous, current) => previous.username != current.username,
  111. builder: (context, state) {
  112. return Container(
  113. height: 50,
  114. padding: EdgeInsets.symmetric(horizontal: 17),
  115. decoration: BoxDecoration(
  116. shape: BoxShape.rectangle,
  117. borderRadius: BorderRadius.circular(10),
  118. color: COLOR_CONST.GRAY7),
  119. child: Center(
  120. child: TextFormField(
  121. focusNode: usernameFocus,
  122. textInputAction: TextInputAction.next,
  123. onChanged: (username) => context
  124. .bloc<LoginBloc>()
  125. .add(LoginUsernameChanged(username)),
  126. autovalidate: true,
  127. validator: (_) {
  128. return state.username.invalid
  129. ? 'Vui lòng nhập tên đăng nhập'
  130. : null;
  131. },
  132. onFieldSubmitted: (_) {
  133. usernameFocus.unfocus();
  134. FocusScope.of(context).requestFocus(nextFocus);
  135. },
  136. maxLines: 1,
  137. keyboardType: TextInputType.text,
  138. obscureText: false,
  139. textAlign: TextAlign.left,
  140. decoration: InputDecoration.collapsed(
  141. hintText: 'Tên đăng nhập',
  142. ),
  143. ),
  144. ));
  145. },
  146. );
  147. }
  148. }
  149. class _PasswordInput extends StatelessWidget {
  150. final FocusNode passwordFocus;
  151. _PasswordInput({this.passwordFocus});
  152. @override
  153. Widget build(BuildContext context) {
  154. return BlocBuilder<LoginBloc, LoginState>(
  155. buildWhen: (previous, current) => previous.password != current.password,
  156. builder: (context, state) {
  157. return Container(
  158. height: 50,
  159. padding: EdgeInsets.symmetric(horizontal: 17),
  160. decoration: BoxDecoration(
  161. shape: BoxShape.rectangle,
  162. borderRadius: BorderRadius.circular(10),
  163. color: COLOR_CONST.GRAY7),
  164. child: Center(
  165. child: TextFormField(
  166. focusNode: passwordFocus,
  167. onChanged: (password) => context
  168. .bloc<LoginBloc>()
  169. .add(LoginPasswordChanged(password)),
  170. autovalidate: true,
  171. validator: (_) {
  172. return state.password.invalid
  173. ? 'Vui lòng nhập mật khẩu'
  174. : null;
  175. },
  176. onFieldSubmitted: (_) {
  177. passwordFocus.unfocus();
  178. if (state.status.isValidated) {
  179. context.bloc<LoginBloc>().add(const LoginSubmitted());
  180. }
  181. },
  182. maxLines: 1,
  183. keyboardType: TextInputType.text,
  184. obscureText: true,
  185. textAlign: TextAlign.left,
  186. decoration: InputDecoration.collapsed(
  187. hintText: 'Mật khẩu',
  188. ),
  189. ),
  190. ));
  191. },
  192. );
  193. }
  194. }
  195. class _LoginButton extends StatelessWidget {
  196. @override
  197. Widget build(BuildContext context) {
  198. return BlocBuilder<LoginBloc, LoginState>(
  199. buildWhen: (previous, current) => previous.status != current.status,
  200. builder: (context, state) {
  201. return SizedBox(
  202. width: double.infinity,
  203. height: 55,
  204. child: FlatButton(
  205. onPressed: () {
  206. if (state.status.isValidated) {
  207. context.bloc<LoginBloc>().add(const LoginSubmitted());
  208. }
  209. },
  210. color: state.status.isValidated
  211. ? COLOR_CONST.DEFAULT
  212. : COLOR_CONST.GRAY1_50,
  213. shape: RoundedRectangleBorder(
  214. borderRadius: new BorderRadius.circular(7.0),
  215. ),
  216. child: Text(
  217. 'Đăng nhập'.toUpperCase(),
  218. style: TextStyle(
  219. fontWeight: FontWeight.bold, color: COLOR_CONST.WHITE),
  220. ),
  221. ),
  222. );
  223. },
  224. );
  225. }
  226. }