import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import 'package:tdesign_flutter/tdesign_flutter.dart'; import '../../core/i18n/app_localizations.dart'; import '../../core/i18n/locale_provider.dart'; import '../../core/theme/app_colors.dart'; import '../../shared/widgets/profile_menu_item.dart'; import '../shell/nav_bar_config.dart'; class ProfilePage extends ConsumerWidget { const ProfilePage({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final l10n = AppLocalizations.of(context); final location = GoRouterState.of(context).uri.toString(); final currentLocale = ref.watch(localeProvider); if (location.startsWith('/profile')) { ref .read(navBarConfigProvider.notifier) .update( NavBarConfig( title: l10n.get('tabProfile'), showBack: true, leadingIcon: Icons.close, ), ); } return SingleChildScrollView( physics: const AlwaysScrollableScrollPhysics(), child: Column( children: [ const SizedBox(height: 16), // 用户信息头部 _buildUserInfoCard(context, l10n), const SizedBox(height: 16), // 菜单列表 Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: Column( children: [ ProfileMenuItem( icon: Icons.checklist, label: l10n.get('myApprovals'), onTap: () => context.push('/expense/list'), ), const SizedBox(height: 8), ProfileMenuItem( icon: Icons.description, label: l10n.get('myApplications'), onTap: () => context.push('/expense-apply/list'), ), const SizedBox(height: 8), ProfileMenuItem( icon: Icons.receipt_long, label: l10n.get('myExpenses'), onTap: () => context.push('/expense/list'), ), const SizedBox(height: 8), ProfileMenuItem( icon: Icons.edit_note, label: l10n.get('outingLog'), onTap: () => context.push('/outing-log/list'), ), const SizedBox(height: 8), ProfileMenuItem( icon: Icons.campaign, label: l10n.get('announcements'), onTap: () => context.push('/announcement/list'), ), const SizedBox(height: 8), ProfileMenuItem( icon: Icons.settings, label: l10n.get('settings'), ), const SizedBox(height: 8), ProfileMenuItem( icon: Icons.language, label: l10n.get('language'), trailing: _localeName(currentLocale), onTap: () => _showLanguageSheet(context, ref, currentLocale), ), const SizedBox(height: 8), ProfileMenuItem( icon: Icons.info_outline, label: l10n.get('about'), ), ], ), ), const SizedBox(height: 8), TDFooter(TDFooterType.text, text: l10n.get('version')), ], ), ); } Widget _buildUserInfoCard(BuildContext context, AppLocalizations l10n) { return Container( margin: const EdgeInsets.symmetric(horizontal: 16), padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 24), decoration: BoxDecoration( color: AppColors.bgCard, borderRadius: BorderRadius.circular(12), ), child: Row( children: [ // 头像 Container( width: 64, height: 64, decoration: const BoxDecoration( color: AppColors.primaryLight, shape: BoxShape.circle, ), child: Center( child: Text( '张', style: const TextStyle( fontSize: 28, fontWeight: FontWeight.w700, color: AppColors.primary, ), ), ), ), const SizedBox(width: 16), // 用户信息 Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( l10n.get('userName'), style: const TextStyle( fontSize: AppFontSizes.title, fontWeight: FontWeight.w600, color: AppColors.textPrimary, ), ), const SizedBox(height: AppSpacing.xs), Text( l10n.get('salesDepartment'), style: const TextStyle( fontSize: AppFontSizes.body, color: AppColors.textSecondary, ), ), ], ), ), // 箭头 const Icon( Icons.chevron_right, size: 16, color: AppColors.textPlaceholder, ), ], ), ); } String _localeName(Locale locale) { if (locale.languageCode == 'zh' && locale.countryCode == 'TW') { return '繁體中文'; } if (locale.languageCode == 'en') { return 'English'; } return '简体中文'; } void _showLanguageSheet( BuildContext context, WidgetRef ref, Locale currentLocale, ) { final languages = [ (label: '简体中文', locale: const Locale('zh', 'CN')), (label: 'English', locale: const Locale('en')), (label: '繁體中文', locale: const Locale('zh', 'TW')), ]; TDActionSheet.showListActionSheet( Navigator.of(context, rootNavigator: true).context, showCancel: false, useSafeArea: false, items: languages.map((lang) { final isSelected = lang.locale.languageCode == currentLocale.languageCode && lang.locale.countryCode == currentLocale.countryCode; return TDActionSheetItem( label: isSelected ? '${lang.label} ✓' : lang.label, textStyle: TextStyle( color: isSelected ? AppColors.primary : AppColors.textPrimary, fontWeight: isSelected ? FontWeight.w600 : FontWeight.normal, ), ); }).toList(), onSelected: (item, index) { ref.read(localeProvider.notifier).setLocale(languages[index].locale); }, ); } }