auth_login_page.dart 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. import 'package:cpt_auth/modules/auth_login/auth_login_state.dart';
  2. import 'package:cs_resources/generated/assets.dart';
  3. import 'package:cs_resources/generated/l10n.dart';
  4. import 'package:cs_resources/theme/app_colors_theme.dart';
  5. import 'package:flutter/gestures.dart';
  6. import 'package:flutter/material.dart';
  7. import 'package:auto_route/auto_route.dart';
  8. import 'package:hooks_riverpod/hooks_riverpod.dart';
  9. import 'package:router/ext/auto_router_extensions.dart';
  10. import 'package:widgets/ext/ex_widget.dart';
  11. import 'package:widgets/my_appbar.dart';
  12. import 'package:widgets/my_button.dart';
  13. import 'package:widgets/my_load_image.dart';
  14. import 'package:widgets/my_text_field.dart';
  15. import 'package:widgets/my_text_view.dart';
  16. import 'package:widgets/shatter/custom_check_box.dart';
  17. import 'package:widgets/widget_export.dart';
  18. import '../../router/page/auth_page_router.dart';
  19. import 'auth_login_view_model.dart';
  20. /*
  21. * 用户的登录页面
  22. */
  23. @RoutePage()
  24. class AuthLoginPage extends HookConsumerWidget {
  25. const AuthLoginPage({Key? key}) : super(key: key);
  26. //启动当前页面
  27. static void startInstance({BuildContext? context}) {
  28. if (context != null) {
  29. context.router.navigate(const AuthLoginPageRoute());
  30. } else {
  31. appRouter.navigate(const AuthLoginPageRoute());
  32. }
  33. }
  34. @override
  35. Widget build(BuildContext context, WidgetRef ref) {
  36. final viewModel = ref.read(authLoginViewModelProvider.notifier);
  37. final state = ref.watch(authLoginViewModelProvider);
  38. return Scaffold(
  39. appBar: MyAppBar.appBar(context, "", showBackButton: false),
  40. backgroundColor: context.appColors.backgroundDefault,
  41. body: SingleChildScrollView(
  42. scrollDirection: Axis.vertical,
  43. physics: const BouncingScrollPhysics(),
  44. child: Container(
  45. margin: const EdgeInsets.symmetric(horizontal: 38),
  46. width: double.infinity,
  47. child: Column(
  48. mainAxisSize: MainAxisSize.max,
  49. crossAxisAlignment: CrossAxisAlignment.center,
  50. children: [
  51. //顶部Logo
  52. const MyAssetImage(
  53. Assets.assetsYyHomeLogo,
  54. width: 85.5,
  55. height: 85.5,
  56. ).marginOnly(top: 45, bottom: 45),
  57. // 登录表单 - 账号
  58. _buildInputLayout(
  59. context,
  60. state,
  61. "account",
  62. textInputAction: TextInputAction.next,
  63. errorText: state.accountErrorText,
  64. onSubmit: (formKey, value) {
  65. state.formData[formKey]!['focusNode'].unfocus();
  66. FocusScope.of(context).requestFocus(state.formData['password']!['focusNode']);
  67. },
  68. ),
  69. // 登录表单 - 密码
  70. _buildInputLayout(
  71. context,
  72. state,
  73. "password",
  74. marginTop: 15,
  75. obscureText: !state.pwdVisibility,
  76. errorText: state.passwordErrorText,
  77. showRightIcon: true,
  78. rightWidget: IconButton(
  79. highlightColor: Colors.transparent,
  80. splashColor: Colors.transparent,
  81. icon: state.pwdVisibility
  82. ? const MyAssetImage(
  83. Assets.authPasswordHide,
  84. width: 22.5,
  85. height: 16.5,
  86. )
  87. : const MyAssetImage(
  88. Assets.authPasswordShow,
  89. width: 22.5,
  90. height: 16.5,
  91. ),
  92. onPressed: () {
  93. viewModel.switchPwdVisibility();
  94. },
  95. ),
  96. onSubmit: (formKey, value) {
  97. state.formData[formKey]!['focusNode'].unfocus();
  98. viewModel.doLogin();
  99. },
  100. ),
  101. //登录按钮
  102. MyButton(
  103. onPressed: viewModel.doLogin,
  104. text: S.current.login,
  105. isEnabled: state.isLoginBtnEnable,
  106. textColor: Colors.white,
  107. disabledTextColor: Colors.white,
  108. backgroundColor: context.appColors.btnBgDefault,
  109. disabledBackgroundColor: context.appColors.btnBgDefault.withOpacity(0.2),
  110. fontWeight: FontWeight.w500,
  111. type: ClickType.throttle,
  112. minHeight: 50,
  113. radius: 5,
  114. ).marginOnly(top: 20, bottom: 23),
  115. //忘记密码
  116. MyTextView(
  117. S.current.forgot_password,
  118. isFontMedium: true,
  119. fontSize: 16,
  120. textColor: context.appColors.textPrimary,
  121. onClick: viewModel.gotoForgotPage,
  122. ),
  123. //创建账户-注册
  124. MyButton(
  125. onPressed: viewModel.gotoSignUpPage,
  126. text: S.current.create_new_yy_home_account,
  127. textColor: Colors.white,
  128. backgroundColor: context.appColors.btnBgDefault,
  129. fontWeight: FontWeight.w500,
  130. type: ClickType.throttle,
  131. minHeight: 50,
  132. radius: 5,
  133. ).marginOnly(top: 28, bottom: 30),
  134. //同意协议
  135. Row(
  136. mainAxisSize: MainAxisSize.min,
  137. children: [
  138. MyAssetImage(
  139. state.isAgreeTerms ? Assets.baseServiceCheckBoxChecked : Assets.baseServiceCheckBoxUncheck,
  140. width: 15.5,
  141. height: 15.5,
  142. ).onTap(viewModel.switchAgreeTerms, padding: 10),
  143. RichText(
  144. text: TextSpan(
  145. children: [
  146. TextSpan(
  147. text: S.current.agree_to,
  148. style: TextStyle(color: context.appColors.textDarkGray, fontWeight: FontWeight.w500, fontSize: 15), // 灰色文本
  149. ),
  150. const TextSpan(
  151. text: " ",
  152. ),
  153. TextSpan(
  154. text: S.current.terms_of_service,
  155. style: TextStyle(color: context.appColors.textPrimary, fontWeight: FontWeight.w500, fontSize: 15), // 蓝色文本
  156. recognizer: TapGestureRecognizer()..onTap = viewModel.gotoTermsPage,
  157. ),
  158. ],
  159. ),
  160. ),
  161. ],
  162. ),
  163. //结束
  164. ],
  165. ),
  166. ),
  167. ),
  168. );
  169. }
  170. /// 输入框 账号与密码
  171. Widget _buildInputLayout(
  172. BuildContext context,
  173. LoginState state,
  174. String key, {
  175. double marginTop = 0,
  176. bool? showRightIcon = false, //是否展示右侧的布局
  177. Widget? rightWidget, //右侧的布局
  178. TextInputType textInputType = TextInputType.text,
  179. String? errorText,
  180. bool obscureText = false,
  181. TextInputAction textInputAction = TextInputAction.done,
  182. Function? onSubmit,
  183. }) {
  184. return IgnoreKeyboardDismiss(
  185. child: MyTextField(
  186. key,
  187. fillBackgroundColor: context.appColors.authFiledBG,
  188. state.formData[key]!['value'],
  189. hintText: state.formData[key]!['hintText'],
  190. hintStyle: TextStyle(
  191. color: context.appColors.authFiledHint,
  192. fontSize: 16.0,
  193. fontWeight: FontWeight.w500,
  194. ),
  195. controller: state.formData[key]!['controller'],
  196. focusNode: state.formData[key]!['focusNode'],
  197. margin: EdgeInsets.only(top: marginTop),
  198. padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 3),
  199. showDivider: false,
  200. height: 44,
  201. style: TextStyle(
  202. color: context.appColors.authFiledText,
  203. fontSize: 16.0,
  204. fontWeight: FontWeight.w500,
  205. ),
  206. inputType: textInputType,
  207. textInputAction: textInputAction,
  208. onSubmit: onSubmit,
  209. cursorColor: context.appColors.authFiledText,
  210. obscureText: obscureText,
  211. errorText: errorText,
  212. showLeftIcon: true,
  213. showRightIcon: showRightIcon,
  214. rightWidget: rightWidget,
  215. ),
  216. );
  217. }
  218. }