import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../../../core/l10n/app_localizations.dart'; import '../../../core/theme/app_colors.dart'; import '../../../core/utils/number_format.dart'; import '../../../data/models/home/top_trader.dart'; import '../../../providers/auth_provider.dart'; import '../../../providers/top_trader_provider.dart'; /// 顶级交易专家横向卡片区块 class TopTradersSection extends ConsumerWidget { const TopTradersSection({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final cs = Theme.of(context).colorScheme; final state = ref.watch(topTraderProvider); if (state.isLoading) { return const Padding( padding: EdgeInsets.symmetric(vertical: 24), child: Center(child: CircularProgressIndicator(strokeWidth: 2)), ); } if (state.traders.isEmpty) return const SizedBox.shrink(); return Column( children: [ // 标题 Padding( padding: const EdgeInsets.fromLTRB(16, 8, 16, 12), child: Row( children: [ Text( AppLocalizations.of(context)!.topTraders, style: TextStyle( color: cs.onSurface, fontSize: 17, fontWeight: FontWeight.w700, ), ), const Spacer(), GestureDetector( onTap: () => context.go('/copy-trading'), child: Icon(Icons.chevron_right, color: cs.onSurface.withAlpha(100), size: 22), ), ], ), ), // 交易专家卡片列表 SizedBox( height: 240, child: ListView.separated( scrollDirection: Axis.horizontal, padding: const EdgeInsets.symmetric(horizontal: 16), itemCount: state.traders.length, separatorBuilder: (_, __) => const SizedBox(width: 12), itemBuilder: (context, index) => _TraderCard(trader: state.traders[index]), ), ), const SizedBox(height: 16), ], ); } } // ── 交易员卡片 ───────────────────────────────────────────── class _TraderCard extends ConsumerWidget { const _TraderCard({required this.trader}); final TopTrader trader; @override Widget build(BuildContext context, WidgetRef ref) { final cs = Theme.of(context).colorScheme; final isDark = Theme.of(context).brightness == Brightness.dark; final screenWidth = MediaQuery.of(context).size.width; // 左边距16 + 右侧留出约36px的下一张预览 + 间距12 final cardWidth = screenWidth - 16 - 12 - 36; return Container( width: cardWidth, padding: const EdgeInsets.fromLTRB(16, 20, 16, 14), decoration: BoxDecoration( color: isDark ? AppColors.darkBgSecondary : AppColors.lightBgSecondary, borderRadius: BorderRadius.circular(16), border: Border.all(color: cs.outline.withAlpha(30)), ), child: Column( children: [ // 头像:深色圆形底 + 头像/字母 Container( width: 60, height: 60, decoration: BoxDecoration( color: AppColors.darkAvatarBg, shape: BoxShape.circle, border: Border.all(color: AppColors.brand, width: 2.5), ), child: trader.avatar.isNotEmpty ? ClipOval( child: Image.network( trader.avatar, fit: BoxFit.cover, errorBuilder: (_, __, ___) => _AvatarLetter(trader: trader), ), ) : _AvatarLetter(trader: trader), ), const SizedBox(height: 10), // 昵称 Text( trader.nickname, style: TextStyle( color: cs.onSurface, fontSize: 15, fontWeight: FontWeight.w600, ), maxLines: 1, overflow: TextOverflow.ellipsis, ), const SizedBox(height: 14), // 数据行 Row( children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( AppLocalizations.of(context)!.twoWeekReturn, style: TextStyle( color: cs.onSurface.withAlpha(120), fontSize: 11), ), const SizedBox(height: 4), Text( '${trader.dayYield30 >= 0 ? '+' : ''}${formatPrice(trader.dayYield30, decimalPlaces: 2)}%', style: TextStyle( color: AppColors.changeColor(trader.dayYield30), fontSize: 16, fontWeight: FontWeight.w700, ), ), ], ), ), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ Text( AppLocalizations.of(context)!.twoWeekCopyIncome, style: TextStyle( color: cs.onSurface.withAlpha(120), fontSize: 11), ), const SizedBox(height: 4), Text( trader.profitAmount != 0 ? '${trader.profitAmount >= 0 ? '+' : ''}${formatPrice(trader.profitAmount, decimalPlaces: 2)}' : '--', style: TextStyle( color: trader.profitAmount != 0 ? AppColors.changeColor(trader.profitAmount) : cs.onSurface, fontSize: 14, fontWeight: FontWeight.w600, ), ), ], ), ), ], ), const Spacer(), // 跟单按钮 SizedBox( width: double.infinity, height: 40, child: ElevatedButton( onPressed: () { if (!ref.read(isLoggedInProvider)) { context.push('/login'); return; } if (trader.id.isNotEmpty) { context.push('/trader-detail/${trader.id}'); } else { context.push('/copy-trading'); } }, style: ElevatedButton.styleFrom( backgroundColor: AppColors.brand, foregroundColor: Colors.black, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), elevation: 0, ), child: Text( AppLocalizations.of(context)!.copyTrading, style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w600), ), ), ), ], ), ); } } class _AvatarLetter extends StatelessWidget { const _AvatarLetter({required this.trader}); final TopTrader trader; @override Widget build(BuildContext context) { return Center( child: Text( trader.avatarLetter, style: const TextStyle( color: Colors.white, fontSize: 22, fontWeight: FontWeight.w700, ), ), ); } }