import 'package:flutter/material.dart'; import '../../../../app/i18n/app_localizations.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. 登录页 - 手机号/邮箱+密码 / 验证码快捷登录 class LoginPage extends StatefulWidget { const LoginPage({super.key}); @override State createState() => _LoginPageState(); } class _LoginPageState extends State with SingleTickerProviderStateMixin { late TabController _tabController; final _phoneController = TextEditingController(); final _passwordController = TextEditingController(); final _codeController = TextEditingController(); bool _obscurePassword = true; @override void initState() { super.initState(); _tabController = TabController(length: 2, vsync: this); } @override void dispose() { _tabController.dispose(); _phoneController.dispose(); _passwordController.dispose(); _codeController.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: Padding( padding: AppSpacing.pagePadding, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 16), Text(context.t('login.title'), style: AppTypography.displayMedium), const SizedBox(height: 8), Text( context.t('login.subtitle'), style: AppTypography.bodyLarge.copyWith(color: AppColors.textSecondary), ), const SizedBox(height: 32), // Tab: Password / SMS Code Container( decoration: BoxDecoration( color: AppColors.gray50, borderRadius: AppSpacing.borderRadiusFull, ), child: TabBar( controller: _tabController, indicator: BoxDecoration( color: AppColors.surface, borderRadius: AppSpacing.borderRadiusFull, boxShadow: AppSpacing.shadowSm, ), indicatorSize: TabBarIndicatorSize.tab, dividerColor: Colors.transparent, labelColor: AppColors.textPrimary, unselectedLabelColor: AppColors.textTertiary, labelStyle: AppTypography.labelMedium, tabs: [ Tab(text: context.t('login.passwordTab')), Tab(text: context.t('login.codeTab')), ], ), ), const SizedBox(height: 24), Expanded( child: TabBarView( controller: _tabController, children: [ _buildPasswordLogin(), _buildCodeLogin(), ], ), ), ], ), ), ), ); } Widget _buildPasswordLogin() { return Column( children: [ // Phone/Email Input TextField( controller: _phoneController, keyboardType: TextInputType.phone, decoration: InputDecoration( hintText: context.t('login.phoneOrEmail'), prefixIcon: Icon(Icons.person_outline_rounded, color: AppColors.textTertiary), ), ), const SizedBox(height: 16), // Password Input TextField( controller: _passwordController, obscureText: _obscurePassword, decoration: InputDecoration( hintText: context.t('login.password'), 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: 12), // Forgot Password Align( alignment: Alignment.centerRight, child: GestureDetector( onTap: () { Navigator.pushNamed(context, '/forgot-password'); }, child: Text(context.t('login.forgotPassword'), style: AppTypography.labelSmall.copyWith( color: AppColors.primary, )), ), ), const SizedBox(height: 24), // Login Button GenexButton( label: context.t('login.submit'), onPressed: () { Navigator.pushReplacementNamed(context, '/main'); }, ), ], ); } Widget _buildCodeLogin() { return Column( children: [ // Phone Input TextField( keyboardType: TextInputType.phone, decoration: InputDecoration( hintText: context.t('login.phone'), prefixIcon: Icon(Icons.phone_android_rounded, color: AppColors.textTertiary), ), ), const SizedBox(height: 16), // Code Input + Send Button Row( children: [ Expanded( child: TextField( controller: _codeController, keyboardType: TextInputType.number, decoration: InputDecoration( hintText: context.t('login.verifyCode'), prefixIcon: Icon(Icons.shield_outlined, color: AppColors.textTertiary), ), ), ), const SizedBox(width: 12), SizedBox( height: AppSpacing.inputHeight, child: GenexButton( label: context.t('login.getCode'), variant: GenexButtonVariant.secondary, size: GenexButtonSize.medium, fullWidth: false, onPressed: () { // SMS: send verification code }, ), ), ], ), const SizedBox(height: 24), GenexButton( label: context.t('login.submit'), onPressed: () { Navigator.pushReplacementNamed(context, '/main'); }, ), ], ); } }