import 'package:flutter/material.dart'; import '../../../../app/theme/app_colors.dart'; import '../../../../app/theme/app_typography.dart'; import '../../../../app/theme/app_spacing.dart'; import '../../../../shared/widgets/genex_button.dart'; /// A1. 手机号注册页 /// /// 手机号输入、获取验证码、设置密码、用户协议勾选 /// 注册成功后后台静默创建MPC钱包 class RegisterPage extends StatefulWidget { final bool isEmail; const RegisterPage({super.key, this.isEmail = false}); @override State createState() => _RegisterPageState(); } class _RegisterPageState extends State { final _accountController = TextEditingController(); final _codeController = TextEditingController(); final _passwordController = TextEditingController(); bool _obscurePassword = true; bool _agreeTerms = false; @override void dispose() { _accountController.dispose(); _codeController.dispose(); _passwordController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( leading: IconButton( icon: const Icon(Icons.arrow_back_ios_new_rounded, size: 20), onPressed: () => Navigator.of(context).pop(), ), ), body: SafeArea( child: SingleChildScrollView( padding: AppSpacing.pagePadding, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 16), Text('创建账号', style: AppTypography.displayMedium), const SizedBox(height: 8), Text( widget.isEmail ? '使用邮箱注册 Genex 账号' : '使用手机号注册 Genex 账号', style: AppTypography.bodyLarge.copyWith(color: AppColors.textSecondary), ), const SizedBox(height: 40), // Step indicator _buildStepIndicator(), const SizedBox(height: 32), // Account Input (Phone/Email) Text( widget.isEmail ? '邮箱地址' : '手机号', style: AppTypography.labelMedium, ), const SizedBox(height: 8), TextField( controller: _accountController, keyboardType: widget.isEmail ? TextInputType.emailAddress : TextInputType.phone, decoration: InputDecoration( hintText: widget.isEmail ? '请输入邮箱地址' : '请输入手机号', prefixIcon: Icon( widget.isEmail ? Icons.email_outlined : Icons.phone_android_rounded, color: AppColors.textTertiary, ), ), ), const SizedBox(height: 20), // Verification Code Text('验证码', style: AppTypography.labelMedium), const SizedBox(height: 8), Row( children: [ Expanded( child: TextField( controller: _codeController, keyboardType: TextInputType.number, maxLength: 6, decoration: const InputDecoration( hintText: '请输入6位验证码', counterText: '', prefixIcon: Icon(Icons.shield_outlined, color: AppColors.textTertiary), ), ), ), const SizedBox(width: 12), SizedBox( height: AppSpacing.inputHeight, child: GenexButton( label: '获取验证码', variant: GenexButtonVariant.secondary, size: GenexButtonSize.medium, fullWidth: false, onPressed: () {}, ), ), ], ), const SizedBox(height: 20), // Password Text('设置密码', style: AppTypography.labelMedium), const SizedBox(height: 8), TextField( controller: _passwordController, obscureText: _obscurePassword, decoration: InputDecoration( hintText: '8-20位,含字母和数字', prefixIcon: const Icon(Icons.lock_outline_rounded, color: AppColors.textTertiary), suffixIcon: IconButton( icon: Icon( _obscurePassword ? Icons.visibility_off_outlined : Icons.visibility_outlined, color: AppColors.textTertiary, size: 20, ), onPressed: () => setState(() => _obscurePassword = !_obscurePassword), ), ), ), const SizedBox(height: 8), _buildPasswordStrength(), const SizedBox(height: 32), // Terms Agreement Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( width: 20, height: 20, child: Checkbox( value: _agreeTerms, onChanged: (v) => setState(() => _agreeTerms = v ?? false), activeColor: AppColors.primary, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4)), ), ), const SizedBox(width: 8), Expanded( child: GestureDetector( onTap: () => setState(() => _agreeTerms = !_agreeTerms), child: RichText( text: TextSpan( style: AppTypography.bodySmall, children: [ const TextSpan(text: '我已阅读并同意 '), TextSpan( text: '《用户协议》', style: AppTypography.bodySmall.copyWith(color: AppColors.primary), ), const TextSpan(text: ' 和 '), TextSpan( text: '《隐私政策》', style: AppTypography.bodySmall.copyWith(color: AppColors.primary), ), ], ), ), ), ), ], ), const SizedBox(height: 32), // Register Button GenexButton( label: '注册', onPressed: _agreeTerms ? () { // Auth: register → silent MPC wallet creation } : null, ), const SizedBox(height: 40), ], ), ), ), ); } Widget _buildStepIndicator() { return Row( children: [ _buildStep(1, '验证', true), _buildStepLine(true), _buildStep(2, '设密码', true), _buildStepLine(false), _buildStep(3, '完成', false), ], ); } Widget _buildStep(int number, String label, bool active) { return Column( children: [ Container( width: 28, height: 28, decoration: BoxDecoration( color: active ? AppColors.primary : AppColors.gray200, shape: BoxShape.circle, ), child: Center( child: Text( '$number', style: TextStyle( color: active ? Colors.white : AppColors.textTertiary, fontSize: 13, fontWeight: FontWeight.w600, ), ), ), ), const SizedBox(height: 4), Text( label, style: AppTypography.caption.copyWith( color: active ? AppColors.primary : AppColors.textTertiary, ), ), ], ); } Widget _buildStepLine(bool active) { return Expanded( child: Container( height: 2, margin: const EdgeInsets.only(bottom: 18), color: active ? AppColors.primary : AppColors.gray200, ), ); } Widget _buildPasswordStrength() { final password = _passwordController.text; final hasLength = password.length >= 8; final hasLetter = RegExp(r'[a-zA-Z]').hasMatch(password); final hasDigit = RegExp(r'\d').hasMatch(password); return Row( children: [ _buildCheck('8位以上', hasLength), const SizedBox(width: 16), _buildCheck('含字母', hasLetter), const SizedBox(width: 16), _buildCheck('含数字', hasDigit), ], ); } Widget _buildCheck(String label, bool passed) { return Row( mainAxisSize: MainAxisSize.min, children: [ Icon( passed ? Icons.check_circle_rounded : Icons.circle_outlined, size: 14, color: passed ? AppColors.success : AppColors.textTertiary, ), const SizedBox(width: 4), Text( label, style: AppTypography.caption.copyWith( color: passed ? AppColors.success : AppColors.textTertiary, ), ), ], ); } }