// Author: fruit.com.cn part of 'auth_view.dart'; class _AuthCardState { const _AuthCardState({ required this.l10n, required this.status, required this.fields, }); final AppLocalizations l10n; final _AuthFormStatus status; final _AuthFieldControllers fields; } class _AuthFormStatus { const _AuthFormStatus({ required this.signUpMode, required this.busy, required this.errorMessage, required this.fieldError, required this.obscurePassword, }); final bool signUpMode; final bool busy; final String? errorMessage; final AuthFieldError? fieldError; final bool obscurePassword; } class _AuthFieldControllers { const _AuthFieldControllers({ required this.email, required this.password, required this.emailFocus, required this.passwordFocus, }); final TextEditingController email; final TextEditingController password; final FocusNode emailFocus; final FocusNode passwordFocus; } class _AuthCardCallbacks { const _AuthCardCallbacks({ required this.onModeSelected, required this.onEmailChanged, required this.onPasswordChanged, required this.onTogglePasswordVisibility, required this.onSubmit, }); final ValueChanged onModeSelected; final ValueChanged onEmailChanged; final ValueChanged onPasswordChanged; final VoidCallback onTogglePasswordVisibility; final VoidCallback onSubmit; } class _AuthCard extends StatelessWidget { const _AuthCard({required this.state, required this.callbacks}); final _AuthCardState state; final _AuthCardCallbacks callbacks; @override Widget build(BuildContext context) { final l10n = state.l10n; final status = state.status; // 不再做卡片盒子,表单直接排在红光晕背景上。 return Column( key: const Key('auth-card'), crossAxisAlignment: CrossAxisAlignment.stretch, children: [ _AuthModeSwitch( l10n: l10n, signUpMode: status.signUpMode, busy: status.busy, onSelected: callbacks.onModeSelected, ), const SizedBox(height: 24), Text( status.signUpMode ? l10n.authSignUpTitle : l10n.authSignInTitle, style: const TextStyle( color: AppColors.onSurface, fontSize: 24, fontWeight: FontWeight.w600, height: 1.2, ), ), const SizedBox(height: 6), Text( status.signUpMode ? l10n.authSignUpSubtitle : l10n.authSubtitle, style: const TextStyle( color: AppColors.muted, fontSize: AppDimens.body, height: 1.45, ), ), const SizedBox(height: 20), _AuthFields(state: state, callbacks: callbacks), if (status.errorMessage != null) ...[ const SizedBox(height: 14), _AuthError(message: status.errorMessage!), ], const SizedBox(height: 22), _AuthSubmitButton(state: state, onSubmit: callbacks.onSubmit), ], ); } } class _AuthModeSwitch extends StatelessWidget { const _AuthModeSwitch({ required this.l10n, required this.signUpMode, required this.busy, required this.onSelected, }); final AppLocalizations l10n; final bool signUpMode; final bool busy; final ValueChanged onSelected; @override Widget build(BuildContext context) { return Row( key: const Key('auth-switch-mode'), children: [ _ModeTab( segmentKey: const Key('auth-mode-sign-in'), label: l10n.signIn, selected: !signUpMode, onTap: busy ? null : () => onSelected(false), ), const SizedBox(width: AppDimens.followingSegmentGap), _ModeTab( segmentKey: const Key('auth-mode-sign-up'), label: l10n.signUp, selected: signUpMode, onTap: busy ? null : () => onSelected(true), ), ], ); } }