import 'package:flutter/material.dart'; import 'package:shadcn_ui/shadcn_ui.dart'; import 'package:provider/provider.dart'; import 'package:google_fonts/google_fonts.dart'; import '../../../core/theme/app_color_scheme.dart'; import '../../../core/theme/app_spacing.dart'; import '../../../providers/auth_provider.dart'; import '../../../providers/theme_provider.dart'; import '../auth/login_page.dart'; import '../../components/glass_panel.dart'; import '../../components/neon_glow.dart'; /// 菜单项数据模型 class _MenuItem { final IconData icon; final String title; final String? subtitle; final Color? iconColor; final VoidCallback onTap; const _MenuItem({ required this.icon, required this.title, this.subtitle, this.iconColor, required this.onTap, }); } /// 我的页面 - Material Design 3 风格 class MinePage extends StatefulWidget { const MinePage({super.key}); @override State createState() => _MinePageState(); } class _MinePageState extends State with AutomaticKeepAliveClientMixin { @override bool get wantKeepAlive => true; @override Widget build(BuildContext context) { super.build(context); return Scaffold( backgroundColor: AppColorScheme.darkBackground, body: Consumer( builder: (context, auth, _) { return SingleChildScrollView( padding: AppSpacing.pagePadding, child: Column( children: [ _UserCard(user: auth.user), SizedBox(height: AppSpacing.md), _MenuList(onShowComingSoon: _showComingSoon, onShowAbout: _showAboutDialog), SizedBox(height: AppSpacing.xl), _LogoutButton(onLogout: () => _handleLogout(auth)), SizedBox(height: AppSpacing.lg), // 版本信息 Text( 'System Build v1.0.0-Neo', style: TextStyle( fontSize: 10, color: AppColorScheme.darkOnSurfaceVariant.withValues(alpha: 0.4), letterSpacing: 0.3, ), ), ], ), ); }, ), ); } void _showComingSoon(String feature) { showShadDialog( context: context, builder: (context) => ShadDialog.alert( title: Row( children: [ Icon(Icons.construction, color: AppColorScheme.warning, size: 20), SizedBox(width: AppSpacing.sm), const Text('功能开发中'), ], ), description: Text('$feature功能正在开发中,敬请期待~'), actions: [ ShadButton( child: const Text('知道了'), onPressed: () => Navigator.of(context).pop(), ), ], ), ); } void _showAboutDialog() { showShadDialog( context: context, builder: (context) => ShadDialog( title: Row( children: [ _AppLogo(radius: 20, fontSize: 20), SizedBox(width: AppSpacing.sm + AppSpacing.xs), const Text('模拟所'), ], ), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '虚拟货币模拟交易平台', style: TextStyle(color: AppColorScheme.darkOnSurfaceVariant), ), SizedBox(height: AppSpacing.md), _InfoRow(icon: Icons.code, text: '版本: 1.0.0'), SizedBox(height: AppSpacing.sm), _InfoRow(icon: Icons.favorite, text: 'Built with Flutter & Material Design 3'), ], ), actions: [ ShadButton( child: const Text('确定'), onPressed: () => Navigator.of(context).pop(), ), ], ), ); } void _handleLogout(AuthProvider auth) { showShadDialog( context: context, builder: (ctx) => ShadDialog.alert( title: const Text('确认退出'), description: const Text('确定要退出登录吗?'), actions: [ ShadButton.outline( child: const Text('取消'), onPressed: () => Navigator.of(ctx).pop(), ), ShadButton.destructive( child: const Text('退出'), onPressed: () async { Navigator.of(ctx).pop(); await auth.logout(); if (ctx.mounted) { Navigator.of(ctx).pushAndRemoveUntil( MaterialPageRoute(builder: (_) => const LoginPage()), (route) => false, ); } }, ), ], ), ); } } /// 用户卡片组件 - Material Design 3 风格 class _UserCard extends StatelessWidget { final dynamic user; const _UserCard({required this.user}); @override Widget build(BuildContext context) { return GlassPanel( padding: EdgeInsets.all(AppSpacing.lg + AppSpacing.sm), child: Row( children: [ // 头像 - 带霓虹边框 Stack( children: [ Container( decoration: BoxDecoration( shape: BoxShape.circle, boxShadow: [ BoxShadow( color: AppColorScheme.neonGlowPrimary, blurRadius: 20, ), ], ), child: _AppLogo(radius: 36, fontSize: 28, text: user?.avatarText), ), // 验证徽章 Positioned( bottom: 0, right: 0, child: Container( padding: EdgeInsets.all(4), decoration: BoxDecoration( color: AppColorScheme.darkTertiary, shape: BoxShape.circle, border: Border.all( color: AppColorScheme.darkBackground, width: 2, ), ), child: Icon( Icons.verified, size: 14, color: AppColorScheme.darkOnTertiary, ), ), ), ], ), SizedBox(width: AppSpacing.md + AppSpacing.xs), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( user?.username ?? '未登录', style: GoogleFonts.spaceGrotesk( fontSize: 24, fontWeight: FontWeight.bold, color: AppColorScheme.darkOnSurface, ), ), SizedBox(height: AppSpacing.sm), // 用户等级标签 Container( padding: EdgeInsets.symmetric( horizontal: AppSpacing.md, vertical: AppSpacing.xs, ), decoration: BoxDecoration( color: AppColorScheme.darkPrimary.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(AppRadius.full), border: Border.all( color: AppColorScheme.darkPrimary.withValues(alpha: 0.2), ), ), child: Text( 'NORMAL USER', style: TextStyle( fontSize: 10, fontWeight: FontWeight.w700, letterSpacing: 0.2, color: AppColorScheme.darkPrimary, ), ), ), ], ), ), Icon( LucideIcons.chevronRight, color: AppColorScheme.darkOnSurfaceVariant, ), ], ), ); } } /// 应用 Logo 组件 class _AppLogo extends StatelessWidget { final double radius; final double fontSize; final String? text; const _AppLogo({required this.radius, required this.fontSize, this.text}); @override Widget build(BuildContext context) { return CircleAvatar( radius: radius, backgroundColor: AppColorScheme.darkPrimary.withValues(alpha: 0.2), child: Text( text ?? '₿', style: TextStyle( fontSize: fontSize, color: AppColorScheme.darkPrimary, fontWeight: FontWeight.bold, ), ), ); } } /// 信息行组件 class _InfoRow extends StatelessWidget { final IconData icon; final String text; const _InfoRow({required this.icon, required this.text}); @override Widget build(BuildContext context) { return Row( children: [ Icon(icon, size: 14, color: AppColorScheme.darkOnSurfaceVariant), SizedBox(width: AppSpacing.sm), Text( text, style: TextStyle( fontSize: 12, color: AppColorScheme.darkOnSurfaceVariant, ), ), ], ); } } /// 菜单列表组件 - Glass Panel 风格 class _MenuList extends StatelessWidget { final void Function(String) onShowComingSoon; final VoidCallback onShowAbout; const _MenuList({required this.onShowComingSoon, required this.onShowAbout}); @override Widget build(BuildContext context) { final themeProvider = context.watch(); return GlassPanel( padding: EdgeInsets.zero, borderRadius: BorderRadius.circular(AppRadius.xxl), child: Column( children: [ // 主题切换开关 _ThemeToggleTile(isDarkMode: themeProvider.isDarkMode), _buildDivider(), // 菜单项 ..._buildMenuItems(), ], ), ); } Widget _buildDivider() { return Container( margin: EdgeInsets.only(left: 56), height: 1, color: AppColorScheme.glassPanelBorder, ); } List _buildMenuItems() { final items = [ _MenuItem( icon: LucideIcons.userCheck, title: '实名认证', subtitle: '完成实名认证,解锁更多功能', iconColor: AppColorScheme.darkPrimary, onTap: () => onShowComingSoon('实名认证'), ), _MenuItem( icon: LucideIcons.shield, title: '安全设置', subtitle: '密码、二次验证等安全设置', iconColor: AppColorScheme.darkSecondary, onTap: () => onShowComingSoon('安全设置'), ), _MenuItem( icon: LucideIcons.bell, title: '消息通知', subtitle: '管理消息推送设置', iconColor: AppColorScheme.darkTertiary, onTap: () => onShowComingSoon('消息通知'), ), _MenuItem( icon: LucideIcons.settings, title: '系统设置', subtitle: '主题、语言等偏好设置', iconColor: AppColorScheme.darkPrimary, onTap: () => onShowComingSoon('系统设置'), ), _MenuItem( icon: LucideIcons.info, title: '关于我们', subtitle: '版本信息与用户协议', iconColor: AppColorScheme.darkOnSurfaceVariant, onTap: onShowAbout, ), ]; return [ for (var i = 0; i < items.length; i++) ...[ _MenuItemTile(item: items[i]), if (i < items.length - 1) _buildDivider(), ], ]; } } /// 主题切换组件 class _ThemeToggleTile extends StatelessWidget { final bool isDarkMode; const _ThemeToggleTile({required this.isDarkMode}); @override Widget build(BuildContext context) { final themeProvider = context.read(); return InkWell( onTap: () => themeProvider.toggleTheme(), child: Padding( padding: EdgeInsets.symmetric( horizontal: AppSpacing.md, vertical: AppSpacing.sm + AppSpacing.xs, ), child: Row( children: [ _MenuIcon( icon: isDarkMode ? LucideIcons.moon : LucideIcons.sun, color: AppColorScheme.darkPrimary, ), SizedBox(width: AppSpacing.sm + AppSpacing.xs), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '深色模式', style: GoogleFonts.spaceGrotesk( fontSize: 14, fontWeight: FontWeight.w500, color: AppColorScheme.darkOnSurface, ), ), SizedBox(height: AppSpacing.xs / 2), Text( isDarkMode ? '当前:深色主题' : '当前:浅色主题', style: TextStyle( fontSize: 11, color: AppColorScheme.darkOnSurfaceVariant, ), ), ], ), ), Switch( value: isDarkMode, onChanged: (_) => themeProvider.toggleTheme(), activeTrackColor: AppColorScheme.darkPrimary.withValues(alpha: 0.5), activeColor: AppColorScheme.darkPrimary, ), ], ), ), ); } } /// 菜单项组件 class _MenuItemTile extends StatelessWidget { final _MenuItem item; const _MenuItemTile({required this.item}); @override Widget build(BuildContext context) { return InkWell( onTap: item.onTap, child: Padding( padding: EdgeInsets.symmetric( horizontal: AppSpacing.md, vertical: AppSpacing.sm + AppSpacing.xs, ), child: Row( children: [ _MenuIcon(icon: item.icon, color: item.iconColor), SizedBox(width: AppSpacing.sm + AppSpacing.xs), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( item.title, style: GoogleFonts.spaceGrotesk( fontSize: 14, fontWeight: FontWeight.w500, color: AppColorScheme.darkOnSurface, ), ), if (item.subtitle != null) ...[ SizedBox(height: AppSpacing.xs / 2), Text( item.subtitle!, style: TextStyle( fontSize: 11, color: AppColorScheme.darkOnSurfaceVariant, ), ), ], ], ), ), Icon( LucideIcons.chevronRight, size: 18, color: AppColorScheme.darkOnSurfaceVariant, ), ], ), ), ); } } /// 菜单图标组件 - Material Design 3 风格 class _MenuIcon extends StatelessWidget { final IconData icon; final Color? color; const _MenuIcon({required this.icon, this.color}); @override Widget build(BuildContext context) { final iconColor = color ?? AppColorScheme.darkPrimary; return Container( width: 40, height: 40, decoration: BoxDecoration( color: iconColor.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(AppRadius.md + AppSpacing.xs), border: Border.all( color: iconColor.withValues(alpha: 0.2), ), ), child: Icon(icon, size: 20, color: iconColor), ); } } /// 退出登录按钮 - 带霓虹光效 class _LogoutButton extends StatelessWidget { final VoidCallback onLogout; const _LogoutButton({required this.onLogout}); @override Widget build(BuildContext context) { return NeonButton( text: 'Logout Terminal', type: NeonButtonType.error, icon: Icons.logout, onPressed: onLogout, width: double.infinity, showGlow: true, ); } }