285 lines
9.2 KiB
Dart
285 lines
9.2 KiB
Dart
import 'package:flutter/material.dart';
|
||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||
import 'package:go_router/go_router.dart';
|
||
|
||
import '../../../shared/providers/auth_provider.dart';
|
||
|
||
class HomeScreen extends ConsumerWidget {
|
||
const HomeScreen({super.key});
|
||
|
||
@override
|
||
Widget build(BuildContext context, WidgetRef ref) {
|
||
final authState = ref.watch(authProvider);
|
||
|
||
return Scaffold(
|
||
appBar: AppBar(
|
||
title: const Text('Drama Ling'),
|
||
actions: [
|
||
IconButton(
|
||
icon: const Icon(Icons.person),
|
||
onPressed: () => context.go('/profile'),
|
||
),
|
||
],
|
||
),
|
||
body: SafeArea(
|
||
child: SingleChildScrollView(
|
||
padding: const EdgeInsets.all(24.0),
|
||
child: Column(
|
||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||
children: [
|
||
// Welcome Section
|
||
Container(
|
||
padding: const EdgeInsets.all(20),
|
||
decoration: BoxDecoration(
|
||
gradient: LinearGradient(
|
||
colors: [
|
||
Theme.of(context).colorScheme.primary,
|
||
Theme.of(context).colorScheme.primary.withOpacity(0.8),
|
||
],
|
||
begin: Alignment.topLeft,
|
||
end: Alignment.bottomRight,
|
||
),
|
||
borderRadius: BorderRadius.circular(16),
|
||
),
|
||
child: Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
Text(
|
||
'歡迎回來,${authState.displayName ?? '學習者'}!',
|
||
style: Theme.of(context).textTheme.headlineSmall?.copyWith(
|
||
color: Colors.white,
|
||
fontWeight: FontWeight.bold,
|
||
),
|
||
),
|
||
const SizedBox(height: 8),
|
||
Text(
|
||
'繼續您的語言學習之旅',
|
||
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
|
||
color: Colors.white.withOpacity(0.9),
|
||
),
|
||
),
|
||
const SizedBox(height: 16),
|
||
Row(
|
||
children: [
|
||
_buildStatCard('今日學習', '25分鐘', Icons.timer, context),
|
||
const SizedBox(width: 16),
|
||
_buildStatCard('連續天數', '7天', Icons.local_fire_department, context),
|
||
],
|
||
),
|
||
],
|
||
),
|
||
),
|
||
|
||
const SizedBox(height: 32),
|
||
|
||
// Learning Options
|
||
Text(
|
||
'選擇學習方式',
|
||
style: Theme.of(context).textTheme.headlineSmall?.copyWith(
|
||
fontWeight: FontWeight.bold,
|
||
),
|
||
),
|
||
const SizedBox(height: 16),
|
||
|
||
// Learning Cards
|
||
_buildLearningCard(
|
||
context,
|
||
'詞彙練習',
|
||
'學習新詞彙,擴充詞彙量',
|
||
Icons.book_outlined,
|
||
Colors.blue,
|
||
() => context.go('/vocabulary'),
|
||
),
|
||
|
||
const SizedBox(height: 16),
|
||
|
||
_buildLearningCard(
|
||
context,
|
||
'對話練習',
|
||
'AI互動對話,提升口說能力',
|
||
Icons.chat_bubble_outline,
|
||
Colors.green,
|
||
() => context.go('/dialogue'),
|
||
),
|
||
|
||
const SizedBox(height: 16),
|
||
|
||
_buildLearningCard(
|
||
context,
|
||
'限時挑戰',
|
||
'測試反應速度和語言技能',
|
||
Icons.timer_outlined,
|
||
Colors.orange,
|
||
() => context.go('/challenge'),
|
||
),
|
||
|
||
const SizedBox(height: 32),
|
||
|
||
// Progress Section
|
||
Container(
|
||
padding: const EdgeInsets.all(20),
|
||
decoration: BoxDecoration(
|
||
color: Theme.of(context).cardColor,
|
||
borderRadius: BorderRadius.circular(16),
|
||
boxShadow: [
|
||
BoxShadow(
|
||
color: Colors.black.withOpacity(0.05),
|
||
blurRadius: 10,
|
||
offset: const Offset(0, 2),
|
||
),
|
||
],
|
||
),
|
||
child: Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
Text(
|
||
'學習進度',
|
||
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
||
fontWeight: FontWeight.bold,
|
||
),
|
||
),
|
||
const SizedBox(height: 16),
|
||
_buildProgressItem('詞彙掌握', 0.7, '70%', context),
|
||
const SizedBox(height: 12),
|
||
_buildProgressItem('對話流暢度', 0.5, '50%', context),
|
||
const SizedBox(height: 12),
|
||
_buildProgressItem('聽力理解', 0.8, '80%', context),
|
||
],
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
Widget _buildStatCard(String title, String value, IconData icon, BuildContext context) {
|
||
return Expanded(
|
||
child: Container(
|
||
padding: const EdgeInsets.all(12),
|
||
decoration: BoxDecoration(
|
||
color: Colors.white.withOpacity(0.2),
|
||
borderRadius: BorderRadius.circular(12),
|
||
),
|
||
child: Column(
|
||
children: [
|
||
Icon(icon, color: Colors.white, size: 24),
|
||
const SizedBox(height: 4),
|
||
Text(
|
||
value,
|
||
style: const TextStyle(
|
||
color: Colors.white,
|
||
fontWeight: FontWeight.bold,
|
||
fontSize: 16,
|
||
),
|
||
),
|
||
Text(
|
||
title,
|
||
style: TextStyle(
|
||
color: Colors.white.withOpacity(0.8),
|
||
fontSize: 12,
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
Widget _buildLearningCard(
|
||
BuildContext context,
|
||
String title,
|
||
String subtitle,
|
||
IconData icon,
|
||
Color color,
|
||
VoidCallback onTap,
|
||
) {
|
||
return Card(
|
||
child: InkWell(
|
||
onTap: onTap,
|
||
borderRadius: BorderRadius.circular(16),
|
||
child: Container(
|
||
padding: const EdgeInsets.all(20),
|
||
child: Row(
|
||
children: [
|
||
Container(
|
||
width: 50,
|
||
height: 50,
|
||
decoration: BoxDecoration(
|
||
color: color.withOpacity(0.1),
|
||
borderRadius: BorderRadius.circular(12),
|
||
),
|
||
child: Icon(
|
||
icon,
|
||
color: color,
|
||
size: 28,
|
||
),
|
||
),
|
||
const SizedBox(width: 16),
|
||
Expanded(
|
||
child: Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
Text(
|
||
title,
|
||
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
||
fontWeight: FontWeight.bold,
|
||
),
|
||
),
|
||
const SizedBox(height: 4),
|
||
Text(
|
||
subtitle,
|
||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.7),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
Icon(
|
||
Icons.arrow_forward_ios,
|
||
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.5),
|
||
size: 16,
|
||
),
|
||
],
|
||
),
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
Widget _buildProgressItem(String title, double progress, String percentage, BuildContext context) {
|
||
return Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
Row(
|
||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||
children: [
|
||
Text(
|
||
title,
|
||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||
fontWeight: FontWeight.w500,
|
||
),
|
||
),
|
||
Text(
|
||
percentage,
|
||
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||
color: Theme.of(context).colorScheme.primary,
|
||
fontWeight: FontWeight.bold,
|
||
),
|
||
),
|
||
],
|
||
),
|
||
const SizedBox(height: 8),
|
||
LinearProgressIndicator(
|
||
value: progress,
|
||
backgroundColor: Theme.of(context).colorScheme.primary.withOpacity(0.1),
|
||
valueColor: AlwaysStoppedAnimation<Color>(
|
||
Theme.of(context).colorScheme.primary,
|
||
),
|
||
),
|
||
],
|
||
);
|
||
}
|
||
} |