Merge branch 'review-mode-fix' into 'master'

feat: HistoryCard navigation to direct users to ReviewScreen, and refactor...

See merge request profile-image/kedaireka/polinema-adapative-learning/mobile-adaptive-learning!19
This commit is contained in:
Naresh Pratista 2024-11-28 07:07:17 +00:00
commit 09d264ed59
13 changed files with 297 additions and 152 deletions

View File

@ -1 +1 @@
const String baseUrl = 'http://54.173.167.62/'; const String baseUrl = 'https://1252-114-6-25-184.ngrok-free.app/';

View File

@ -7,7 +7,7 @@ class HistoryRepository {
HistoryRepository(this._dioClient); HistoryRepository(this._dioClient);
Future<List<LearningHistory>> getLearningHistory( Future<List<HistoryModel>> getLearningHistory(
String sectionId, String sectionId,
String token, String token,
) async { ) async {
@ -23,9 +23,7 @@ class HistoryRepository {
if (historyData.isEmpty) { if (historyData.isEmpty) {
return []; // Mengembalikan list kosong jika tidak ada data return []; // Mengembalikan list kosong jika tidak ada data
} }
return historyData return historyData.map((json) => HistoryModel.fromJson(json)).toList();
.map((json) => LearningHistory.fromJson(json))
.toList();
} else { } else {
throw Exception( throw Exception(
'Failed to load learning history: ${response.statusMessage}'); 'Failed to load learning history: ${response.statusMessage}');

View File

@ -1,6 +1,7 @@
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
class LearningHistory { class HistoryModel {
final String idStudentLearning;
final int? score; final int? score;
final String currentLevel; final String currentLevel;
final String? nextLevel; final String? nextLevel;
@ -9,7 +10,8 @@ class LearningHistory {
final String sectionName; final String sectionName;
final bool isPass; final bool isPass;
LearningHistory({ HistoryModel({
required this.idStudentLearning,
required this.score, required this.score,
required this.currentLevel, required this.currentLevel,
required this.nextLevel, required this.nextLevel,
@ -19,8 +21,9 @@ class LearningHistory {
required this.isPass, required this.isPass,
}); });
factory LearningHistory.fromJson(Map<String, dynamic> json) { factory HistoryModel.fromJson(Map<String, dynamic> json) {
return LearningHistory( return HistoryModel(
idStudentLearning: json['ID_STUDENT_LEARNING'],
score: json['SCORE'] ?? 0, score: json['SCORE'] ?? 0,
currentLevel: json['CURRENT_LEVEL'] ?? 'Unknown', currentLevel: json['CURRENT_LEVEL'] ?? 'Unknown',
nextLevel: json['NEXT_LEVEL'], nextLevel: json['NEXT_LEVEL'],

View File

@ -7,7 +7,7 @@ import 'package:english_learning/features/history/models/history_model.dart';
class HistoryProvider with ChangeNotifier { class HistoryProvider with ChangeNotifier {
final HistoryRepository _repository; final HistoryRepository _repository;
final SectionProvider _sectionProvider; final SectionProvider _sectionProvider;
List<LearningHistory> _learningHistory = []; List<HistoryModel> _historyModel = [];
int _selectedPageIndex = 0; int _selectedPageIndex = 0;
bool _isLoading = false; bool _isLoading = false;
String? _error; String? _error;
@ -18,7 +18,7 @@ class HistoryProvider with ChangeNotifier {
this._sectionProvider, this._sectionProvider,
); );
List<LearningHistory> get learningHistory => _learningHistory; List<HistoryModel> get historyModel => _historyModel;
int get selectedPageIndex => _selectedPageIndex; int get selectedPageIndex => _selectedPageIndex;
bool get isLoading => _isLoading; bool get isLoading => _isLoading;
String? get error => _error; String? get error => _error;
@ -46,13 +46,13 @@ class HistoryProvider with ChangeNotifier {
String firstSectionId = _sectionProvider.sections.first.id; String firstSectionId = _sectionProvider.sections.first.id;
// Fetch history for the first section // Fetch history for the first section
_learningHistory = _historyModel =
await _repository.getLearningHistory(firstSectionId, token); await _repository.getLearningHistory(firstSectionId, token);
_error = null; _error = null;
_isInitialized = true; // Mark as initialized _isInitialized = true; // Mark as initialized
} catch (e) { } catch (e) {
_error = 'Error loading data: ${e.toString()}'; _error = 'Error loading data: ${e.toString()}';
_learningHistory = []; _historyModel = [];
} finally { } finally {
_isLoading = false; _isLoading = false;
notifyListeners(); notifyListeners();
@ -78,11 +78,11 @@ class HistoryProvider with ChangeNotifier {
try { try {
final history = await _repository.getLearningHistory(sectionId, token); final history = await _repository.getLearningHistory(sectionId, token);
_learningHistory = history; _historyModel = history;
_error = null; _error = null;
} catch (e) { } catch (e) {
_error = 'Error fetching learning history: ${e.toString()}'; _error = 'Error fetching learning history: ${e.toString()}';
_learningHistory = []; _historyModel = [];
} finally { } finally {
_isLoading = false; _isLoading = false;
notifyListeners(); notifyListeners();
@ -151,14 +151,14 @@ class HistoryProvider with ChangeNotifier {
await _sectionProvider.fetchSections(token); await _sectionProvider.fetchSections(token);
if (_sectionProvider.sections.isNotEmpty) { if (_sectionProvider.sections.isNotEmpty) {
String firstSectionId = _sectionProvider.sections.first.id; String firstSectionId = _sectionProvider.sections.first.id;
_learningHistory = _historyModel =
await _repository.getLearningHistory(firstSectionId, token); await _repository.getLearningHistory(firstSectionId, token);
} else { } else {
_error = 'No sections available'; _error = 'No sections available';
} }
} catch (e) { } catch (e) {
_error = 'Error loading data: ${e.toString()}'; _error = 'Error loading data: ${e.toString()}';
_learningHistory = []; // Clear the list in case of error _historyModel = []; // Clear the list in case of error
} finally { } finally {
_isLoading = false; _isLoading = false;
notifyListeners(); notifyListeners();

View File

@ -144,7 +144,7 @@ class _HistoryScreenState extends State<HistoryScreen> {
} }
// Tampilkan empty state jika tidak ada history // Tampilkan empty state jika tidak ada history
if (historyProvider.learningHistory.isEmpty) { if (historyProvider.historyModel.isEmpty) {
return _buildEmptyState(context); return _buildEmptyState(context);
} }
@ -154,8 +154,8 @@ class _HistoryScreenState extends State<HistoryScreen> {
child: AnimatedSwitcher( child: AnimatedSwitcher(
duration: const Duration(milliseconds: 300), duration: const Duration(milliseconds: 300),
child: ListView.builder( child: ListView.builder(
key: ValueKey(historyProvider.learningHistory.length), key: ValueKey(historyProvider.historyModel.length),
itemCount: historyProvider.learningHistory.length, itemCount: historyProvider.historyModel.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
return AnimatedOpacity( return AnimatedOpacity(
opacity: 1.0, opacity: 1.0,
@ -163,7 +163,7 @@ class _HistoryScreenState extends State<HistoryScreen> {
child: Column( child: Column(
children: [ children: [
ExerciseHistoryCard( ExerciseHistoryCard(
exercise: historyProvider.learningHistory[index], exercise: historyProvider.historyModel[index],
), ),
const SizedBox(height: 8.0), const SizedBox(height: 8.0),
], ],

View File

@ -1,28 +1,47 @@
import 'package:english_learning/features/history/models/history_model.dart'; import 'package:english_learning/features/history/models/history_model.dart';
import 'package:english_learning/features/history/provider/history_provider.dart'; import 'package:english_learning/features/history/provider/history_provider.dart';
import 'package:english_learning/core/utils/styles/theme.dart'; import 'package:english_learning/core/utils/styles/theme.dart';
import 'package:english_learning/features/learning/modules/exercises/screens/review_screen.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class ExerciseHistoryCard extends StatelessWidget { class ExerciseHistoryCard extends StatefulWidget {
final LearningHistory exercise; final HistoryModel exercise;
const ExerciseHistoryCard({ const ExerciseHistoryCard({
super.key, super.key,
required this.exercise, required this.exercise,
}); });
@override
State<ExerciseHistoryCard> createState() => _ExerciseHistoryCardState();
}
class _ExerciseHistoryCardState extends State<ExerciseHistoryCard> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final historyProvider = final historyProvider =
Provider.of<HistoryProvider>(context, listen: false); Provider.of<HistoryProvider>(context, listen: false);
final color = historyProvider.getColorForLevels( final color = historyProvider.getColorForLevels(
exercise.currentLevel, widget.exercise.currentLevel,
exercise.nextLevel, widget.exercise.nextLevel,
exercise.isPass, widget.exercise.isPass,
); );
return Card( return GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ReviewScreen(
idStudentLearning: widget.exercise.idStudentLearning,
topicTitle: widget.exercise.topicName,
topicId: null,
),
),
);
},
child: Card(
color: AppColors.whiteColor, color: AppColors.whiteColor,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0), borderRadius: BorderRadius.circular(12.0),
@ -38,7 +57,7 @@ class ExerciseHistoryCard extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(
exercise.topicName, widget.exercise.topicName,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: AppTextStyles.tetriaryTextStyle.copyWith( style: AppTextStyles.tetriaryTextStyle.copyWith(
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
@ -53,13 +72,13 @@ class ExerciseHistoryCard extends StatelessWidget {
), ),
children: [ children: [
TextSpan( TextSpan(
text: '${exercise.currentLevel}', text: '${widget.exercise.currentLevel}',
style: AppTextStyles.blackTextStyle.copyWith(), style: AppTextStyles.blackTextStyle.copyWith(),
), ),
TextSpan( TextSpan(
text: exercise.isPass text: widget.exercise.isPass
? 'Topic Finished' ? 'Topic Finished'
: '${exercise.nextLevel}', : '${widget.exercise.nextLevel}',
style: AppTextStyles.blackTextStyle.copyWith( style: AppTextStyles.blackTextStyle.copyWith(
color: color, color: color,
), ),
@ -69,7 +88,7 @@ class ExerciseHistoryCard extends StatelessWidget {
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
Text( Text(
'Submission: ${exercise.formattedDate}', 'Submission: ${widget.exercise.formattedDate}',
style: AppTextStyles.disableTextStyle.copyWith( style: AppTextStyles.disableTextStyle.copyWith(
fontSize: 12, fontSize: 12,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
@ -91,7 +110,7 @@ class ExerciseHistoryCard extends StatelessWidget {
borderRadius: BorderRadius.circular(8.0), borderRadius: BorderRadius.circular(8.0),
), ),
child: Text( child: Text(
'${exercise.score}/100', '${widget.exercise.score}/100',
style: TextStyle( style: TextStyle(
color: color, color: color,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
@ -101,6 +120,7 @@ class ExerciseHistoryCard extends StatelessWidget {
], ],
), ),
), ),
),
); );
} }
} }

View File

@ -36,7 +36,7 @@ class ReviewExerciseModel {
} }
class ReviewExerciseDetail { class ReviewExerciseDetail {
final String idStudentExercise; final String? idStudentExercise;
final String idAdminExercise; final String idAdminExercise;
final String title; final String title;
final String question; final String question;
@ -46,14 +46,14 @@ class ReviewExerciseDetail {
final String? video; final String? video;
final String? audio; final String? audio;
final String answerStudent; String answerStudent;
final int isCorrect; int isCorrect;
final double resultScoreStudent; final double resultScoreStudent;
final List<ReviewMultipleChoice>? multipleChoices; final List<ReviewMultipleChoice>? multipleChoices;
final List<ReviewMatchingPair>? matchingPairs; final List<ReviewMatchingPair>? matchingPairs;
ReviewExerciseDetail({ ReviewExerciseDetail({
required this.idStudentExercise, this.idStudentExercise,
required this.idAdminExercise, required this.idAdminExercise,
required this.title, required this.title,
required this.question, required this.question,

View File

@ -374,6 +374,14 @@ class ExerciseProvider extends ChangeNotifier {
// Reset current index // Reset current index
_currentExerciseIndex = 0; _currentExerciseIndex = 0;
// Ensure all exercises are displayed with empty answers for unanswered questions
for (var exercise in _reviewExercises) {
if (exercise.answerStudent.isEmpty) {
exercise.answerStudent = ''; // Set empty answer
exercise.isCorrect = 0; // Mark as incorrect
}
}
} catch (e) { } catch (e) {
print('Error fetching review exercises: $e'); print('Error fetching review exercises: $e');
rethrow; rethrow;

View File

@ -12,15 +12,15 @@ class ExerciseScreen extends StatefulWidget {
final String? levelId; final String? levelId;
final String studentLearningId; final String studentLearningId;
final bool isReview; final bool isReview;
final String topicId; // Tambahkan ini final String topicId;
final String topicTitle; // Tambahkan ini final String topicTitle;
const ExerciseScreen({ const ExerciseScreen({
super.key, super.key,
required this.levelId, required this.levelId,
required this.studentLearningId, required this.studentLearningId,
this.isReview = false,
required this.topicId, required this.topicId,
required this.isReview,
required this.topicTitle, required this.topicTitle,
}); });
@ -36,12 +36,7 @@ class _ExerciseScreenState extends State<ExerciseScreen> {
_scrollController = ScrollController(); _scrollController = ScrollController();
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
final provider = context.read<ExerciseProvider>(); final provider = context.read<ExerciseProvider>();
if (widget.isReview) {
provider.fetchReviewExercises(widget.studentLearningId);
} else {
provider.fetchExercises(widget.levelId!); provider.fetchExercises(widget.levelId!);
}
provider.setStudentLearningId(widget.studentLearningId); provider.setStudentLearningId(widget.studentLearningId);
}); });
} }
@ -70,9 +65,7 @@ class _ExerciseScreenState extends State<ExerciseScreen> {
} }
final currentExercise = provider.currentExercise; final currentExercise = provider.currentExercise;
final hasExercises = widget.isReview final hasExercises = provider.exercises.isNotEmpty;
? provider.reviewExercises.isNotEmpty
: provider.exercises.isNotEmpty;
if (!hasExercises || currentExercise == null) { if (!hasExercises || currentExercise == null) {
return const Scaffold( return const Scaffold(
@ -85,15 +78,6 @@ class _ExerciseScreenState extends State<ExerciseScreen> {
appBar: AppBar( appBar: AppBar(
elevation: 0, elevation: 0,
automaticallyImplyLeading: false, automaticallyImplyLeading: false,
leading: widget.isReview
? IconButton(
icon: const Icon(
BootstrapIcons.arrow_left,
color: AppColors.whiteColor,
),
onPressed: () => Navigator.of(context).pop(),
)
: null, // Show back button only in review mode
iconTheme: const IconThemeData(color: AppColors.whiteColor), iconTheme: const IconThemeData(color: AppColors.whiteColor),
centerTitle: true, centerTitle: true,
title: Text( title: Text(
@ -108,8 +92,7 @@ class _ExerciseScreenState extends State<ExerciseScreen> {
gradient: AppColors.gradientTheme, gradient: AppColors.gradientTheme,
), ),
), ),
actions: !widget.isReview actions: [
? [
IconButton( IconButton(
icon: const Icon( icon: const Icon(
BootstrapIcons.info_circle, BootstrapIcons.info_circle,
@ -118,13 +101,11 @@ class _ExerciseScreenState extends State<ExerciseScreen> {
), ),
onPressed: () => _showInstructions(context), onPressed: () => _showInstructions(context),
), ),
] ],
: null,
), ),
body: SafeArea( body: SafeArea(
child: Column( child: Column(
children: [ children: [
if (!widget.isReview)
const Padding( const Padding(
padding: EdgeInsets.all(16.0), padding: EdgeInsets.all(16.0),
child: ExerciseProgress(), child: ExerciseProgress(),
@ -140,12 +121,12 @@ class _ExerciseScreenState extends State<ExerciseScreen> {
ExerciseContent( ExerciseContent(
key: ValueKey(provider.currentExerciseIndex), key: ValueKey(provider.currentExerciseIndex),
exercise: currentExercise, exercise: currentExercise,
isReview: widget.isReview, isReview: false,
), ),
const SizedBox(height: 24), const SizedBox(height: 24),
ExerciseNavigator( ExerciseNavigator(
onScrollToTop: _scrollToTop, onScrollToTop: _scrollToTop,
isReview: widget.isReview, isReview: false,
topicId: widget.topicId, topicId: widget.topicId,
topicTitle: widget.topicTitle, topicTitle: widget.topicTitle,
), ),

View File

@ -0,0 +1,122 @@
import 'package:bootstrap_icons/bootstrap_icons.dart';
import 'package:english_learning/features/learning/modules/exercises/providers/exercise_provider.dart';
import 'package:english_learning/features/learning/modules/exercises/widgets/content/exercise_content.dart';
import 'package:english_learning/features/learning/modules/exercises/widgets/exercise_navigator.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:english_learning/core/utils/styles/theme.dart';
class ReviewScreen extends StatefulWidget {
final String idStudentLearning;
final String? topicId;
final String topicTitle;
const ReviewScreen({
super.key,
required this.idStudentLearning,
this.topicId,
required this.topicTitle,
});
@override
State<ReviewScreen> createState() => _ReviewScreenState();
}
class _ReviewScreenState extends State<ReviewScreen> {
late ScrollController _scrollController;
@override
void initState() {
super.initState();
_scrollController = ScrollController();
WidgetsBinding.instance.addPostFrameCallback((_) {
final provider = context.read<ExerciseProvider>();
provider.fetchReviewExercises(widget.idStudentLearning);
});
}
@override
void dispose() {
_scrollController.dispose();
super.dispose();
}
void _scrollToTop() {
_scrollController.animateTo(
0,
duration: const Duration(milliseconds: 300),
curve: Curves.easeOut,
);
}
@override
Widget build(BuildContext context) {
return Consumer<ExerciseProvider>(builder: (context, provider, child) {
if (provider.isLoading) {
return const Scaffold(
body: Center(child: CircularProgressIndicator()),
);
}
final currentExercise = provider.currentExercise;
final hasExercises = provider.reviewExercises.isNotEmpty;
if (!hasExercises || currentExercise == null) {
return const Scaffold(
body: Center(child: Text('No review exercises available')),
);
}
return Scaffold(
backgroundColor: AppColors.bgSoftColor,
appBar: AppBar(
elevation: 0,
centerTitle: true,
title: Text(
'${provider.nameTopic} - ${provider.nameLevel}',
style: AppTextStyles.whiteTextStyle.copyWith(
fontSize: 14,
fontWeight: FontWeight.w900,
),
),
flexibleSpace: Container(
decoration: BoxDecoration(
gradient: AppColors.gradientTheme,
),
),
leading: IconButton(
icon: const Icon(
BootstrapIcons.arrow_left,
color: AppColors.whiteColor,
),
onPressed: () => Navigator.of(context).pop(),
),
),
body: SafeArea(
child: SingleChildScrollView(
controller: _scrollController,
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Column(
children: [
const SizedBox(height: 16),
ExerciseContent(
key: ValueKey(provider.currentExerciseIndex),
exercise: currentExercise,
isReview: true,
),
const SizedBox(height: 24),
ExerciseNavigator(
onScrollToTop: _scrollToTop,
isReview: true,
topicId: widget.topicId ?? '',
topicTitle: widget.topicTitle,
),
const SizedBox(height: 32),
],
),
),
),
);
});
}
}

View File

@ -12,14 +12,14 @@ import 'package:provider/provider.dart';
class ExerciseNavigator extends StatelessWidget { class ExerciseNavigator extends StatelessWidget {
final VoidCallback? onScrollToTop; final VoidCallback? onScrollToTop;
final bool isReview; final bool isReview;
final String topicId; final String? topicId;
final String topicTitle; final String topicTitle;
const ExerciseNavigator({ const ExerciseNavigator({
super.key, super.key,
required this.onScrollToTop, required this.onScrollToTop,
this.isReview = false, this.isReview = false,
required this.topicId, this.topicId,
required this.topicTitle, required this.topicTitle,
}); });
@ -48,7 +48,7 @@ class ExerciseNavigator extends StatelessWidget {
score: int.tryParse(result['SCORE'].toString()) ?? 0, score: int.tryParse(result['SCORE'].toString()) ?? 0,
isCompleted: result['IS_PASS'] == 1, isCompleted: result['IS_PASS'] == 1,
stdLearningId: result['STUDENT_LEARNING_ID']?.toString(), stdLearningId: result['STUDENT_LEARNING_ID']?.toString(),
topicId: topicId, topicId: topicId!,
topicTitle: topicTitle, topicTitle: topicTitle,
), ),
), ),

View File

@ -1,6 +1,7 @@
import 'package:bootstrap_icons/bootstrap_icons.dart'; import 'package:bootstrap_icons/bootstrap_icons.dart';
import 'package:english_learning/core/utils/styles/theme.dart'; import 'package:english_learning/core/utils/styles/theme.dart';
import 'package:english_learning/core/widgets/custom_button.dart'; import 'package:english_learning/core/widgets/custom_button.dart';
import 'package:english_learning/features/learning/modules/exercises/screens/review_screen.dart';
import 'package:english_learning/features/learning/modules/level/models/level_model.dart'; import 'package:english_learning/features/learning/modules/level/models/level_model.dart';
import 'package:english_learning/features/learning/modules/level/providers/level_provider.dart'; import 'package:english_learning/features/learning/modules/level/providers/level_provider.dart';
import 'package:english_learning/features/learning/modules/material/screens/material_screen.dart'; import 'package:english_learning/features/learning/modules/material/screens/material_screen.dart';
@ -33,11 +34,9 @@ class PretestCard extends StatelessWidget {
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: (context) => MaterialScreen( builder: (context) => ReviewScreen(
levelId: pretest.idLevel, idStudentLearning: pretest.idStudentLearning!,
isReview: true, topicId: null,
studentLearningId: pretest.idStudentLearning,
topicId: pretest.idTopic,
topicTitle: pretest.nameTopic, topicTitle: pretest.nameTopic,
), ),
), ),

View File

@ -4,6 +4,7 @@ import 'package:english_learning/core/widgets/custom_snackbar.dart';
import 'package:english_learning/core/widgets/global_button.dart'; import 'package:english_learning/core/widgets/global_button.dart';
import 'package:english_learning/features/auth/provider/user_provider.dart'; import 'package:english_learning/features/auth/provider/user_provider.dart';
import 'package:english_learning/features/learning/modules/exercises/screens/exercise_screen.dart'; import 'package:english_learning/features/learning/modules/exercises/screens/exercise_screen.dart';
import 'package:english_learning/features/learning/modules/exercises/screens/review_screen.dart';
import 'package:english_learning/features/learning/modules/level/providers/level_provider.dart'; import 'package:english_learning/features/learning/modules/level/providers/level_provider.dart';
import 'package:english_learning/features/learning/modules/material/widgets/audio_player_widget.dart'; import 'package:english_learning/features/learning/modules/material/widgets/audio_player_widget.dart';
import 'package:english_learning/features/learning/modules/material/widgets/image_widget.dart'; import 'package:english_learning/features/learning/modules/material/widgets/image_widget.dart';
@ -67,8 +68,8 @@ class _MaterialScreenState extends State<MaterialScreen>
Future<void> _createStudentLearning() async { Future<void> _createStudentLearning() async {
if (widget.isReview && widget.studentLearningId != null) { if (widget.isReview && widget.studentLearningId != null) {
// Jika mode review dan studentLearningId tersedia, langsung navigasi ke ExerciseScreen // Jika mode review dan studentLearningId tersedia, langsung navigasi ke ReviewScreen
_navigateToExercise(widget.studentLearningId!); _navigateToReview(widget.studentLearningId!);
return; return;
} }
setState(() { setState(() {
@ -102,7 +103,20 @@ class _MaterialScreenState extends State<MaterialScreen>
builder: (context) => ExerciseScreen( builder: (context) => ExerciseScreen(
levelId: widget.levelId, levelId: widget.levelId,
studentLearningId: studentLearningId, studentLearningId: studentLearningId,
isReview: widget.isReview, isReview: false,
topicId: widget.topicId,
topicTitle: widget.topicTitle,
),
),
);
}
void _navigateToReview(String studentLearningId) {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => ReviewScreen(
idStudentLearning: studentLearningId,
topicId: widget.topicId, topicId: widget.topicId,
topicTitle: widget.topicTitle, topicTitle: widget.topicTitle,
), ),