diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index d0dd89a..82dcef6 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -3,7 +3,7 @@ { ExerciseNavigator( onScrollToTop: _scrollToTop, isReview: widget.isReview, + topicId: widget.topicId, + topicTitle: widget.topicTitle, ), const SizedBox(height: 32), ], diff --git a/lib/features/learning/modules/exercises/widgets/exercise_navigator.dart b/lib/features/learning/modules/exercises/widgets/exercise_navigator.dart index 8a604c3..e30c7a1 100644 --- a/lib/features/learning/modules/exercises/widgets/exercise_navigator.dart +++ b/lib/features/learning/modules/exercises/widgets/exercise_navigator.dart @@ -11,11 +11,15 @@ import 'package:provider/provider.dart'; class ExerciseNavigator extends StatelessWidget { final VoidCallback? onScrollToTop; final bool isReview; + final String topicId; + final String topicTitle; const ExerciseNavigator({ super.key, required this.onScrollToTop, this.isReview = false, + required this.topicId, + required this.topicTitle, }); @override @@ -43,6 +47,8 @@ class ExerciseNavigator extends StatelessWidget { score: int.tryParse(result['SCORE'].toString()) ?? 0, isCompleted: result['IS_PASS'] == 1, stdLearningId: result['STUDENT_LEARNING_ID']?.toString(), + topicId: topicId, + topicTitle: topicTitle, ), ), ); diff --git a/lib/features/learning/modules/feedback/providers/feedback_provider.dart b/lib/features/learning/modules/feedback/providers/feedback_provider.dart deleted file mode 100644 index e69de29..0000000 diff --git a/lib/features/learning/modules/feedback/screens/feedback_screen.dart b/lib/features/learning/modules/feedback/screens/feedback_screen.dart index 435a486..0c1f76c 100644 --- a/lib/features/learning/modules/feedback/screens/feedback_screen.dart +++ b/lib/features/learning/modules/feedback/screens/feedback_screen.dart @@ -2,15 +2,20 @@ import 'package:english_learning/core/widgets/global_button.dart'; import 'package:english_learning/core/utils/styles/theme.dart'; import 'package:english_learning/features/learning/modules/exercises/providers/exercise_provider.dart'; import 'package:english_learning/features/learning/modules/feedback/widgets/feedback_dialog.dart'; +import 'package:english_learning/features/learning/modules/level/screens/level_list_screen.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; class FeedbackScreen extends StatefulWidget { final String stdLearningId; + final String topicId; + final String topicTitle; const FeedbackScreen({ super.key, required this.stdLearningId, + required this.topicId, + required this.topicTitle, }); @override @@ -75,7 +80,16 @@ class _FeedbackScreenState extends State { return FeedbackDialog( onSubmit: () { Navigator.of(dialogContext).pop(); // Close the dialog - Navigator.of(context).pop(); // Return to the previous screen + Navigator.pushAndRemoveUntil( + context, + MaterialPageRoute( + builder: (context) => LevelListScreen( + topicId: widget.topicId, + topicTitle: widget.topicTitle, + ), + ), + (route) => false, // This removes all previous routes + ); }, ); }, @@ -189,16 +203,15 @@ class _FeedbackScreenState extends State { backgroundColor: Colors.transparent, borderColor: AppColors.blueColor, onPressed: () { - // Navigator.push( - // context, - // MaterialPageRoute( - // builder: (context) => LevelListScreen( - // topicId: widget.topicId!, - // topicTitle: widget.topicTitle!, - // ), - // ), - // ); - Navigator.of(context).pop(true); + Navigator.pushReplacement( + context, + MaterialPageRoute( + builder: (context) => LevelListScreen( + topicId: widget.topicId, + topicTitle: widget.topicTitle, + ), + ), + ); }, ) ], diff --git a/lib/features/learning/modules/level/providers/level_provider.dart b/lib/features/learning/modules/level/providers/level_provider.dart index af5730b..ff2b54f 100644 --- a/lib/features/learning/modules/level/providers/level_provider.dart +++ b/lib/features/learning/modules/level/providers/level_provider.dart @@ -46,31 +46,6 @@ class LevelProvider with ChangeNotifier { orElse: () => throw Exception('Pretest not found')); } - // int getLevelScore(String levelId) { - // final level = _levels.firstWhere((level) => level.idLevel == levelId, - // orElse: () => const Level( - // idLevel: '', - // idTopic: '', - // idSection: '', - // nameSection: '', - // nameTopic: '', - // nameLevel: '', - // content: '', - // isPretest: 0, - // timeLevel: '', - // )); - // return level.score ?? 0; - // } - - // bool isLevelAllowed(String levelName) { - // return _unlockedLevels.contains(levelName); - // } - - // bool isLevelCompleted(String levelId) { - // return _lastCompletedLevel != null && - // _lastCompletedLevel!['ID_LEVEL'] == levelId; - // } - bool isPretestFinished(String levelId) { return _levels.any( (level) => level.idLevel == levelId && level.idStudentLearning != null); @@ -98,38 +73,4 @@ class LevelProvider with ChangeNotifier { return _levels.any( (level) => level.idLevel == levelId && level.idStudentLearning != null); } - - // bool isLevelAllowed(String levelId) { - // if (_lastCompletedLevel == null) { - // // Jika tidak ada level yang selesai, hanya pretest yang diizinkan - // return levelId == _levels.first.idLevel; - // } - - // String lastCompletedLevelId = _lastCompletedLevel!['ID_LEVEL']; - // int lastCompletedIndex = - // _levels.indexWhere((level) => level.idLevel == lastCompletedLevelId); - // int currentIndex = _levels.indexWhere((level) => level.idLevel == levelId); - - // // Level diizinkan jika indeksnya kurang dari atau sama dengan indeks terakhir yang selesai + 1 - // return currentIndex <= lastCompletedIndex + 1; - // } - - // bool isLevelAllowed(int levelIndex) { - // if (levelIndex == 0) return true; // Pretest is always allowed - // if (_lastCompletedLevel == null) - // return levelIndex == - // 1; // If no level completed, only first level is allowed - // String lastCompletedLevelId = _lastCompletedLevel!['ID_LEVEL']; - // int lastCompletedIndex = - // _levels.indexWhere((level) => level.idLevel == lastCompletedLevelId); - // return levelIndex <= lastCompletedIndex + 2; - // } - - // bool isLevelFinished(int levelIndex) { - // return _levels[levelIndex].idStudentLearning != null; - // } - - // int getLevelScore(int levelIndex) { - // return _levels[levelIndex].score ?? 0; - // } } diff --git a/lib/features/learning/modules/level/screens/level_list_screen.dart b/lib/features/learning/modules/level/screens/level_list_screen.dart index f215fa9..14530ef 100644 --- a/lib/features/learning/modules/level/screens/level_list_screen.dart +++ b/lib/features/learning/modules/level/screens/level_list_screen.dart @@ -78,43 +78,46 @@ class _LevelListScreenState extends State { .where((level) => level.isPretest == 0) .toList(); - return Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - children: [ - PretestCard( - pretest: pretest, - score: levelProvider.getPretestScore(pretest.idLevel), - isCompleted: - levelProvider.isPretestFinished(pretest.idLevel), - isAllowed: levelProvider.isLevelAllowed(pretest.idLevel), - ), - const SizedBox(height: 12), - Expanded( - child: GridView.builder( - gridDelegate: - const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 2, - childAspectRatio: 1.0, - crossAxisSpacing: 16, - mainAxisSpacing: 16, - ), - itemCount: otherLevels.length, - itemBuilder: (context, index) { - final level = otherLevels[index]; - - return LevelCard( - level: level, - isAllowed: - levelProvider.isLevelAllowed(level.idLevel), - score: levelProvider.getLevelScore(level.idLevel), - isCompleted: - levelProvider.isLevelCompleted(level.idLevel), - ); - }, + return RefreshIndicator( + onRefresh: _fetchLevels, + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + children: [ + PretestCard( + pretest: pretest, + score: levelProvider.getPretestScore(pretest.idLevel), + isCompleted: + levelProvider.isPretestFinished(pretest.idLevel), + isAllowed: levelProvider.isLevelAllowed(pretest.idLevel), ), - ), - ], + const SizedBox(height: 12), + Expanded( + child: GridView.builder( + gridDelegate: + const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + childAspectRatio: 1.0, + crossAxisSpacing: 16, + mainAxisSpacing: 16, + ), + itemCount: otherLevels.length, + itemBuilder: (context, index) { + final level = otherLevels[index]; + + return LevelCard( + level: level, + isAllowed: + levelProvider.isLevelAllowed(level.idLevel), + score: levelProvider.getLevelScore(level.idLevel), + isCompleted: + levelProvider.isLevelCompleted(level.idLevel), + ); + }, + ), + ), + ], + ), ), ); } diff --git a/lib/features/learning/modules/level/widgets/level_card.dart b/lib/features/learning/modules/level/widgets/level_card.dart index 83e2e6d..8c9ebf0 100644 --- a/lib/features/learning/modules/level/widgets/level_card.dart +++ b/lib/features/learning/modules/level/widgets/level_card.dart @@ -141,6 +141,8 @@ class LevelCard extends StatelessWidget { MaterialPageRoute( builder: (context) => MaterialScreen( levelId: level.idLevel, + topicId: level.idTopic, + topicTitle: level.nameTopic, ), ), ); diff --git a/lib/features/learning/modules/level/widgets/pretest_card.dart b/lib/features/learning/modules/level/widgets/pretest_card.dart index 1b4dc8d..00c7475 100644 --- a/lib/features/learning/modules/level/widgets/pretest_card.dart +++ b/lib/features/learning/modules/level/widgets/pretest_card.dart @@ -37,6 +37,8 @@ class PretestCard extends StatelessWidget { levelId: pretest.idLevel, isReview: true, studentLearningId: pretest.idStudentLearning, + topicId: pretest.idTopic, + topicTitle: pretest.nameTopic, ), ), ); @@ -48,6 +50,8 @@ class PretestCard extends StatelessWidget { builder: (context) => MaterialScreen( levelId: pretest.idLevel, isReview: false, + topicId: pretest.idTopic, + topicTitle: pretest.nameTopic, ), ), ); @@ -141,31 +145,6 @@ class PretestCard extends StatelessWidget { width: double.infinity, height: 36, color: isFinished ? Colors.green : AppColors.yellowButtonColor, - // onPressed: () { - // if (!isCompleted) { - // Navigator.push( - // context, - // MaterialPageRoute( - // builder: (context) => MaterialScreen( - // levelId: pretest.idLevel, - // ), - // ), - // ); - // } - // // Jika isCompleted true, tidak melakukan apa-apa - // }, - // onPressed: isAllowed - // ? () { - // Navigator.push( - // context, - // MaterialPageRoute( - // builder: (context) => MaterialScreen( - // levelId: pretest.idLevel, - // ), - // ), - // ); - // } - // : () {}, onPressed: navigateToMaterial, ), ], diff --git a/lib/features/learning/modules/material/screens/material_screen.dart b/lib/features/learning/modules/material/screens/material_screen.dart index 8f11dc4..42a8ea1 100644 --- a/lib/features/learning/modules/material/screens/material_screen.dart +++ b/lib/features/learning/modules/material/screens/material_screen.dart @@ -16,12 +16,16 @@ class MaterialScreen extends StatefulWidget { final String levelId; final bool isReview; final String? studentLearningId; + final String topicId; + final String topicTitle; const MaterialScreen({ super.key, required this.levelId, this.isReview = false, this.studentLearningId, + required this.topicId, + required this.topicTitle, }); @override @@ -100,6 +104,8 @@ class _MaterialScreenState extends State levelId: widget.levelId, studentLearningId: studentLearningId, isReview: widget.isReview, + topicId: widget.topicId, + topicTitle: widget.topicTitle, ), ), ); diff --git a/lib/features/learning/modules/result/screens/result_screen.dart b/lib/features/learning/modules/result/screens/result_screen.dart index 6d8bebc..d8c294f 100644 --- a/lib/features/learning/modules/result/screens/result_screen.dart +++ b/lib/features/learning/modules/result/screens/result_screen.dart @@ -10,6 +10,8 @@ class ResultScreen extends StatelessWidget { final int score; final bool isCompleted; final String? stdLearningId; + final String topicId; + final String topicTitle; const ResultScreen({ super.key, @@ -18,6 +20,8 @@ class ResultScreen extends StatelessWidget { required this.score, required this.isCompleted, this.stdLearningId, + required this.topicId, + required this.topicTitle, }); @override @@ -37,18 +41,24 @@ class ResultScreen extends StatelessWidget { currentLevel: currentLevel, score: score, stdLearningId: stdLearningId ?? '', + topicId: topicId, // Tambahkan ini + topicTitle: topicTitle, // Tambahkan ini ) else if (nextLevel != currentLevel) JumpResultWidget( nextLevel: nextLevel, score: score, stdLearningId: stdLearningId ?? '', + topicId: topicId, // Tambahkan ini + topicTitle: topicTitle, // Tambahkan ini ) else DownResultWidget( nextLevel: nextLevel, score: score, stdLearningId: stdLearningId ?? '', + topicId: topicId, // Tambahkan ini + topicTitle: topicTitle, // Tambahkan ini ), ], ), diff --git a/lib/features/learning/modules/result/widgets/complete_result_widget.dart b/lib/features/learning/modules/result/widgets/complete_result_widget.dart index f6732fb..347be09 100644 --- a/lib/features/learning/modules/result/widgets/complete_result_widget.dart +++ b/lib/features/learning/modules/result/widgets/complete_result_widget.dart @@ -8,12 +8,16 @@ class CompleteResultWidget extends StatelessWidget { final String? currentLevel; final int? score; final String stdLearningId; + final String topicId; + final String topicTitle; const CompleteResultWidget({ super.key, required this.currentLevel, required this.score, required this.stdLearningId, + required this.topicId, + required this.topicTitle, }); @override @@ -57,6 +61,8 @@ class CompleteResultWidget extends StatelessWidget { MaterialPageRoute( builder: (context) => FeedbackScreen( stdLearningId: stdLearningId, + topicId: topicId, // Tambahkan ini + topicTitle: topicTitle, // Tambahkan ini ), ), ); diff --git a/lib/features/learning/modules/result/widgets/down_result_widget.dart b/lib/features/learning/modules/result/widgets/down_result_widget.dart index 00f8339..f22f287 100644 --- a/lib/features/learning/modules/result/widgets/down_result_widget.dart +++ b/lib/features/learning/modules/result/widgets/down_result_widget.dart @@ -8,12 +8,16 @@ class DownResultWidget extends StatelessWidget { final String? nextLevel; final int? score; final String stdLearningId; + final String topicId; + final String topicTitle; const DownResultWidget({ super.key, required this.nextLevel, required this.score, required this.stdLearningId, + required this.topicId, + required this.topicTitle, }); @override @@ -67,6 +71,8 @@ class DownResultWidget extends StatelessWidget { MaterialPageRoute( builder: (context) => FeedbackScreen( stdLearningId: stdLearningId, + topicId: topicId, // Tambahkan ini + topicTitle: topicTitle, // Tambahkan ini ), ), ); diff --git a/lib/features/learning/modules/result/widgets/jump_result_widget.dart b/lib/features/learning/modules/result/widgets/jump_result_widget.dart index 89cb251..04bb499 100644 --- a/lib/features/learning/modules/result/widgets/jump_result_widget.dart +++ b/lib/features/learning/modules/result/widgets/jump_result_widget.dart @@ -8,12 +8,17 @@ class JumpResultWidget extends StatelessWidget { final String? nextLevel; final int? score; final String stdLearningId; + final String topicId; + final String topicTitle; - const JumpResultWidget( - {super.key, - required this.nextLevel, - required this.score, - required this.stdLearningId}); + const JumpResultWidget({ + super.key, + required this.nextLevel, + required this.score, + required this.stdLearningId, + required this.topicId, + required this.topicTitle, + }); @override Widget build(BuildContext context) { @@ -66,6 +71,8 @@ class JumpResultWidget extends StatelessWidget { MaterialPageRoute( builder: (context) => FeedbackScreen( stdLearningId: stdLearningId, + topicId: topicId, // Tambahkan ini + topicTitle: topicTitle, // Tambahkan ini ), ), ); diff --git a/lib/features/learning/modules/topics/screens/topics_list_screen.dart b/lib/features/learning/modules/topics/screens/topics_list_screen.dart index bc332a0..227eef5 100644 --- a/lib/features/learning/modules/topics/screens/topics_list_screen.dart +++ b/lib/features/learning/modules/topics/screens/topics_list_screen.dart @@ -137,7 +137,7 @@ class _TopicsListScreenState extends State { child: Consumer( builder: (context, topicProvider, _) { if (topicProvider.topics.isEmpty) { - return Center(child: CircularProgressIndicator()); + return const Center(child: CircularProgressIndicator()); } else if (topicProvider.error != null) { return const Center(child: Text('No topics available')); } else { @@ -150,7 +150,7 @@ class _TopicsListScreenState extends State { description: topic.description, isCompleted: topic.isCompleted, onTap: () { - Navigator.push( + Navigator.pushReplacement( context, MaterialPageRoute( builder: (context) => LevelListScreen(