Files
ai_english/client/lib/features/home/widgets/learning_stats_card.dart

352 lines
10 KiB
Dart
Raw Normal View History

2025-11-17 13:39:05 +08:00
import 'package:flutter/material.dart';
import '../../../core/theme/app_colors.dart';
import '../../../core/theme/app_text_styles.dart';
import '../../../core/theme/app_dimensions.dart';
/// 学习统计卡片组件
class LearningStatsCard extends StatelessWidget {
const LearningStatsCard({super.key});
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.all(AppDimensions.spacingMd),
decoration: BoxDecoration(
color: AppColors.surface,
borderRadius: BorderRadius.circular(AppDimensions.radiusMd),
boxShadow: [
BoxShadow(
color: AppColors.shadow.withOpacity(0.1),
blurRadius: 8,
offset: const Offset(0, 2),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(
Icons.analytics_outlined,
color: AppColors.primary,
size: 24,
),
const SizedBox(width: AppDimensions.spacingSm),
Text(
'本周学习数据',
style: AppTextStyles.titleMedium.copyWith(
color: AppColors.onSurface,
fontWeight: FontWeight.w600,
),
),
],
),
const SizedBox(height: AppDimensions.spacingLg),
// 统计数据网格
Row(
children: [
Expanded(
child: _buildStatItem(
title: '学习天数',
value: '5',
unit: '',
icon: Icons.calendar_today,
color: AppColors.primary,
),
),
const SizedBox(width: AppDimensions.spacingMd),
Expanded(
child: _buildStatItem(
title: '学习时长',
value: '2.5',
unit: '小时',
icon: Icons.access_time,
color: AppColors.secondary,
),
),
],
),
const SizedBox(height: AppDimensions.spacingMd),
Row(
children: [
Expanded(
child: _buildStatItem(
title: '掌握单词',
value: '128',
unit: '',
icon: Icons.psychology,
color: AppColors.success,
),
),
const SizedBox(width: AppDimensions.spacingMd),
Expanded(
child: _buildStatItem(
title: '练习题目',
value: '45',
unit: '',
icon: Icons.quiz,
color: AppColors.warning,
),
),
],
),
const SizedBox(height: AppDimensions.spacingLg),
// 学习排名
_buildRankingSection(),
const SizedBox(height: AppDimensions.spacingLg),
// 成就徽章
_buildAchievementSection(),
],
),
);
}
/// 构建统计项
Widget _buildStatItem({
required String title,
required String value,
required String unit,
required IconData icon,
required Color color,
}) {
return Container(
padding: const EdgeInsets.all(AppDimensions.spacingMd),
decoration: BoxDecoration(
color: color.withOpacity(0.05),
borderRadius: BorderRadius.circular(AppDimensions.radiusSm),
border: Border.all(
color: color.withOpacity(0.1),
width: 1,
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(
icon,
color: color,
size: 20,
),
const Spacer(),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 6,
vertical: 2,
),
decoration: BoxDecoration(
color: color.withOpacity(0.1),
borderRadius: BorderRadius.circular(8),
),
child: Text(
'+12%',
style: AppTextStyles.labelSmall.copyWith(
color: color,
fontWeight: FontWeight.w600,
),
),
),
],
),
const SizedBox(height: AppDimensions.spacingSm),
RichText(
text: TextSpan(
children: [
TextSpan(
text: value,
style: AppTextStyles.headlineSmall.copyWith(
color: AppColors.onSurface,
fontWeight: FontWeight.w700,
),
),
TextSpan(
text: ' $unit',
style: AppTextStyles.bodySmall.copyWith(
color: AppColors.onSurfaceVariant,
),
),
],
),
),
const SizedBox(height: AppDimensions.spacingXs),
Text(
title,
style: AppTextStyles.bodySmall.copyWith(
color: AppColors.onSurfaceVariant,
),
),
],
),
);
}
/// 构建排名部分
Widget _buildRankingSection() {
return Container(
padding: const EdgeInsets.all(AppDimensions.spacingMd),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
AppColors.primary.withOpacity(0.1),
AppColors.secondary.withOpacity(0.1),
],
),
borderRadius: BorderRadius.circular(AppDimensions.radiusSm),
border: Border.all(
color: AppColors.primary.withOpacity(0.2),
width: 1,
),
),
child: Row(
children: [
Container(
width: 40,
height: 40,
decoration: BoxDecoration(
color: AppColors.primary,
shape: BoxShape.circle,
),
child: Icon(
Icons.emoji_events,
color: AppColors.onPrimary,
size: 24,
),
),
const SizedBox(width: AppDimensions.spacingMd),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'学习排名',
style: AppTextStyles.titleSmall.copyWith(
color: AppColors.primary,
fontWeight: FontWeight.w600,
),
),
const SizedBox(height: 2),
Text(
'本周排名第 8 位,超越了 76% 的用户',
style: AppTextStyles.bodySmall.copyWith(
color: AppColors.onSurfaceVariant,
),
),
],
),
),
Text(
'#8',
style: AppTextStyles.headlineSmall.copyWith(
color: AppColors.primary,
fontWeight: FontWeight.w700,
),
),
],
),
);
}
/// 构建成就部分
Widget _buildAchievementSection() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'最新成就',
style: AppTextStyles.titleSmall.copyWith(
color: AppColors.onSurface,
fontWeight: FontWeight.w600,
),
),
const SizedBox(height: AppDimensions.spacingSm),
Row(
children: [
_buildAchievementBadge(
icon: Icons.local_fire_department,
title: '连续学习',
subtitle: '5天',
color: AppColors.error,
),
const SizedBox(width: AppDimensions.spacingSm),
_buildAchievementBadge(
icon: Icons.speed,
title: '快速学习',
subtitle: '今日',
color: AppColors.success,
),
const SizedBox(width: AppDimensions.spacingSm),
_buildAchievementBadge(
icon: Icons.star,
title: '完美答题',
subtitle: '昨日',
color: AppColors.warning,
),
],
),
],
);
}
/// 构建成就徽章
Widget _buildAchievementBadge({
required IconData icon,
required String title,
required String subtitle,
required Color color,
}) {
return Expanded(
child: Container(
padding: const EdgeInsets.all(AppDimensions.spacingSm),
decoration: BoxDecoration(
color: color.withOpacity(0.1),
borderRadius: BorderRadius.circular(AppDimensions.radiusXs),
border: Border.all(
color: color.withOpacity(0.2),
width: 1,
),
),
child: Column(
children: [
Icon(
icon,
color: color,
size: 20,
),
const SizedBox(height: AppDimensions.spacingXs),
Text(
title,
style: AppTextStyles.labelSmall.copyWith(
color: AppColors.onSurface,
fontWeight: FontWeight.w500,
),
textAlign: TextAlign.center,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
Text(
subtitle,
style: AppTextStyles.labelSmall.copyWith(
color: AppColors.onSurfaceVariant,
fontSize: 10,
),
textAlign: TextAlign.center,
),
],
),
),
);
}
}