import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; import '../../../../core/theme/design_tokens.dart'; import '../../../../shared/widgets/app_pressable.dart'; import '../../../../shared/widgets/toast/toast.dart'; import '../../../../shared/widgets/toast/toast_type.dart'; import '../../../auth/presentation/bloc/auth_bloc.dart'; import '../../../auth/presentation/bloc/auth_event.dart'; import '../../../auth/presentation/bloc/auth_state.dart'; import '../../../../shared/widgets/app_button.dart'; import '../widgets/account_section_card.dart'; import '../widgets/settings_page_scaffold.dart'; class AccountScreen extends StatelessWidget { const AccountScreen({super.key}); static const double _menuItemHeight = AppSpacing.xl * 2 + AppSpacing.md; static const double _menuItemHorizontalPadding = AppSpacing.md; static const double _menuIconSize = 20; static const double _menuChevronSize = 18; @override Widget build(BuildContext context) { return SettingsPageScaffold( title: '账户', onBack: () => context.pop(), body: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [_buildListSurface(context)], ), ); } Widget _buildListSurface(BuildContext context) { return AccountSectionCard( backgroundColor: AppColors.white, borderColor: AppColors.borderSecondary, contentPadding: const EdgeInsets.symmetric( horizontal: AppSpacing.md, vertical: AppSpacing.sm, ), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ _buildMenuItem( icon: Icons.edit, title: '编辑资料', onTap: () => context.push('/edit-profile'), ), _buildDivider(), _buildMenuItem( icon: Icons.logout, title: '退出登录', titleColor: AppColors.feedbackErrorText, iconColor: AppColors.feedbackErrorIcon, trailingColor: AppColors.feedbackErrorIcon, onTap: () => _showLogoutSheet(context), ), ], ), ); } Widget _buildMenuItem({ required IconData icon, required String title, required VoidCallback onTap, Color titleColor = AppColors.slate900, Color iconColor = AppColors.slate500, Color trailingColor = AppColors.slate400, }) { return AppPressable( onTap: onTap, borderRadius: BorderRadius.circular(AppRadius.md), child: Container( constraints: const BoxConstraints(minHeight: _menuItemHeight), padding: const EdgeInsets.symmetric( horizontal: _menuItemHorizontalPadding, vertical: AppSpacing.sm, ), child: Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ SizedBox( width: _menuIconSize, child: Icon(icon, size: _menuIconSize, color: iconColor), ), const SizedBox(width: AppSpacing.md), Text( title, style: TextStyle( fontSize: 16, fontWeight: FontWeight.w600, color: titleColor, ), ), ], ), Icon( Icons.chevron_right, size: _menuChevronSize, color: trailingColor, ), ], ), ), ); } Widget _buildDivider() { return Container( height: 1, margin: const EdgeInsets.only( left: _menuItemHorizontalPadding + _menuIconSize + AppSpacing.md, right: _menuItemHorizontalPadding, ), color: AppColors.borderTertiary, ); } void _showLogoutSheet(BuildContext context) { showModalBottomSheet( context: context, backgroundColor: Colors.transparent, isScrollControlled: true, builder: (sheetContext) => SafeArea( top: false, child: Container( margin: const EdgeInsets.fromLTRB( AppSpacing.md, AppSpacing.none, AppSpacing.md, AppSpacing.md, ), padding: const EdgeInsets.all(AppSpacing.lg), decoration: BoxDecoration( color: AppColors.white, borderRadius: BorderRadius.circular(AppRadius.xl), border: Border.all(color: AppColors.borderSecondary), ), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ const Text( '退出登录', style: TextStyle( fontSize: 18, fontWeight: FontWeight.w700, color: AppColors.slate900, ), textAlign: TextAlign.center, ), const SizedBox(height: AppSpacing.xs), const Text( '确定退出当前账户吗?', style: TextStyle(fontSize: 14, color: AppColors.slate500), textAlign: TextAlign.center, ), const SizedBox(height: AppSpacing.lg), SizedBox( height: 52, child: GestureDetector( onTap: () async { Navigator.of(sheetContext).pop(); final authBloc = context.read(); authBloc.add(AuthLoggedOut()); try { await authBloc.stream .firstWhere((state) => state is AuthUnauthenticated) .timeout(const Duration(seconds: 5)); } catch (_) { if (context.mounted) { Toast.show( context, '退出失败,请稍后重试', type: ToastType.error, ); } return; } if (context.mounted) { context.go('/'); } }, child: Container( decoration: BoxDecoration( color: AppColors.feedbackErrorIcon, borderRadius: BorderRadius.circular(AppRadius.full), ), alignment: Alignment.center, child: const Text( '确认退出', style: TextStyle( fontSize: 15, fontWeight: FontWeight.w700, color: AppColors.white, ), ), ), ), ), const SizedBox(height: AppSpacing.sm), SizedBox( height: 52, child: AppButton( text: '取消', isOutlined: true, onPressed: () => Navigator.of(sheetContext).pop(), ), ), ], ), ), ), ); } }