Files
Vocasia-LMS-Mobile-apps--TA…/lib/screens/course/quiz_result_page.dart

501 lines
24 KiB
Dart

import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:initial_folder/models/quiz_model.dart';
import 'package:initial_folder/models/quiz_perquestion_result_model.dart';
import 'package:initial_folder/models/quiz_question_model.dart';
import 'package:initial_folder/models/quiz_question_result_model.dart';
import 'package:initial_folder/screens/course/play_course_page.dart';
import 'package:initial_folder/screens/course/quiz_page.dart';
import 'package:initial_folder/services/quiz_service.dart';
import 'package:initial_folder/size_config.dart';
import 'package:initial_folder/theme.dart';
import 'package:initial_folder/widgets/login_regist/default_button.dart';
import 'package:tap_debouncer/tap_debouncer.dart';
import 'package:html/parser.dart';
class quiz_resultPage extends StatefulWidget {
final String judulQuiz;
final String lessonId;
final int totalQuiz;
final String allAnswer;
final int IdQuiz;
const quiz_resultPage(
{super.key,
required this.judulQuiz,
required this.lessonId,
required this.totalQuiz,
required this.allAnswer,
required this.IdQuiz});
@override
State<quiz_resultPage> createState() => _quiz_resultPageState();
}
class _quiz_resultPageState extends State<quiz_resultPage> {
QuizQuestionResult? quizQuestionResult;
QuizPerQuestionResult? quizPerQuestionResult;
int currentQuestionIndex = 1; // Menyimpan indeks pertanyaan saat ini
bool fromAmbilLagi = false;
int _selectedQuesNum = 1;
String _selectedQuesText = "";
List<Map<String, dynamic>> allAnswersList = [];
@override
void initState() {
super.initState();
print("ini id apa gatau" + widget.IdQuiz.toString());
// Parsing the allAnswer JSON string to List
allAnswersList =
List<Map<String, dynamic>>.from(json.decode(widget.allAnswer));
getAnswerQuiz();
getQuestionPerNumber();
}
void getAnswerQuiz() {
quiz_service().get_result_quiz(widget.allAnswer).then((value) {
setState(() {
quizQuestionResult = value;
});
});
}
void getQuestionPerNumber() {
print(_selectedQuesNum);
quiz_service()
.get_result_quiz_pernumber(widget.IdQuiz, _selectedQuesNum)
.then((value) {
setState(() {
quizPerQuestionResult = value;
});
});
}
bool _isUserSelectedAnswer(int questionId, int optionIndex) {
for (var answer in allAnswersList) {
if (answer['question_id'] == questionId &&
answer['answers'].contains(optionIndex.toString())) {
return true;
}
}
return false;
}
Widget build(BuildContext context) {
String _parseHtmlString(String htmlText) {
RegExp exp =
RegExp(r"<[^>]*>|&nbsp;", multiLine: true, caseSensitive: true);
return htmlText.replaceAll(exp, '');
}
int countCorrectAnswers() {
if (quizQuestionResult != null && quizQuestionResult!.data.isNotEmpty) {
// Menggunakan metode where untuk menyaring data yang memiliki is_correct true
int correctCount = quizQuestionResult!.data
.where((question) => question.isCorrect == true)
.length;
return correctCount;
} else {
return 0;
}
}
return quizQuestionResult == null
? Center(
child: Scaffold(
body: Center(
child: CircularProgressIndicator(
color: primaryColor,
),
),
))
: PopScope(
child: Scaffold(
appBar: AppBar(
centerTitle: true,
backgroundColor: Colors.transparent,
automaticallyImplyLeading:
false, // Menonaktifkan tombol kembali default
leading: IconButton(
// Menambahkan tombol kustom
icon: Icon(Icons.arrow_back),
onPressed: () {
// Tambahkan fungsi yang diinginkan saat tombol kembali ditekan
Future.delayed(Duration.zero, () {
Navigator.of(context).pop();
});
},
),
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.background,
boxShadow: [
BoxShadow(
color: Theme.of(context).brightness == Brightness.dark
? Colors.black
: Colors.grey,
spreadRadius: 1,
blurRadius: 5,
offset: Offset(0, 1), // Shadow position
),
],
),
child: Column(
children: [
Container(
margin: EdgeInsetsDirectional.only(
top: getProportionateScreenHeight(15)),
height: getProportionateScreenHeight(110),
width: getProportionateScreenWidth(320),
decoration: BoxDecoration(
color: Theme.of(context)
.colorScheme
.primaryContainer,
borderRadius: BorderRadius.circular(15),
boxShadow: [
BoxShadow(
color: Theme.of(context).brightness ==
Brightness.dark
? Colors.black
: Colors.grey,
blurRadius: 2,
spreadRadius: 1,
offset: Offset(0, 0))
]),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Tinjau materi kursus untuk memperluas pembelajaran kamu.', // Menampilkan nomor pertanyaan
textAlign: TextAlign.center,
style: thirdTextStyle.copyWith(
fontWeight: FontWeight.w200,
fontSize: getProportionateScreenWidth(13),
),
),
SizedBox(
height: getProportionateScreenHeight(15),
),
Text(
'Kamu mendapatkan ${countCorrectAnswers()} Dari ${widget.totalQuiz} Benar', // Menampilkan nomor pertanyaan
textAlign: TextAlign.center,
style: thirdTextStyle.copyWith(
fontWeight: FontWeight.w200,
fontSize: getProportionateScreenWidth(13),
),
),
],
),
),
SizedBox(
height: 25,
),
SizedBox(
height: 90, // Adjust height to control the size
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: quizQuestionResult!.data.length,
itemBuilder: (context, index) {
var dataques = quizQuestionResult!.data[index];
return GestureDetector(
onTap: () {
setState(() {
_selectedQuesNum = index + 1;
// getQuestionPerNumber()
_selectedQuesText = dataques.question;
});
getQuestionPerNumber();
// print(
// quizPerQuestionResult!.data.first.title);
// print(dataques.question);
// print(dataques.questionId);
},
child: SizedBox(
width: 80, // Adjust width here
height: 65, // Adjust height here
child: Container(
margin: EdgeInsets.all(10),
decoration: BoxDecoration(
color: Theme.of(context)
.colorScheme
.primaryContainer,
borderRadius:
BorderRadius.circular(15),
boxShadow: [
BoxShadow(
color: Theme.of(context)
.brightness ==
Brightness.dark
? Colors.black
: Colors.grey,
blurRadius: 2,
spreadRadius: 1,
offset: Offset(0, 3))
]),
child: Column(
mainAxisAlignment:
MainAxisAlignment.end,
children: [
Center(
child: Text(
'${index + 1}',
// dataques.isCorrect.toString(),
style: thirdTextStyle.copyWith(
fontSize: 16,
fontWeight: FontWeight.w800),
),
),
SizedBox(
height: 5,
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
height:
getProportionateScreenHeight(
18),
decoration: BoxDecoration(
color: dataques.isCorrect ==
true
? Colors.green
: dataques.isCorrect != true
? Colors.red
: Colors.red,
borderRadius:
BorderRadius.vertical(
bottom: Radius.circular(
15)),
),
child: Center(
child: dataques.isCorrect ==
true
? Icon(
Icons
.check_circle_outline,
color: Colors.white,
size:
getProportionateScreenHeight(
13),
)
: dataques.isCorrect !=
true
? Icon(
Icons
.cancel_outlined,
color:
Colors.white,
size:
getProportionateScreenHeight(
13),
)
: Icon(
Icons
.cancel_outlined,
color:
Colors.white,
size:
getProportionateScreenHeight(
13),
)),
),
),
],
)),
),
);
},
),
),
SizedBox(
height: 15,
)
],
),
),
SizedBox(
height: getProportionateScreenHeight(15),
),
Text(
'Pertanyaan ${_selectedQuesNum}',
style: thirdTextStyle.copyWith(
fontSize: getProportionateScreenWidth(14)),
),
SizedBox(
height: getProportionateScreenHeight(15),
),
Text(
_parseHtmlString(quizPerQuestionResult!.data.first.title),
style: thirdTextStyle.copyWith(
fontSize: getProportionateScreenWidth(14)),
),
Expanded(
child: ListView.builder(
scrollDirection: Axis.vertical,
itemCount:
quizPerQuestionResult!.data.first.options.length,
itemBuilder: (context, index) {
var dataques = quizPerQuestionResult!.data.first;
bool isCorrectAnswer = dataques.correctAnswers
.contains((index + 1).toString());
return Padding(
padding: EdgeInsets.all(10),
child: Container(
decoration: BoxDecoration(
color: fourthColor,
borderRadius: BorderRadius.circular(10),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
height: getProportionateScreenHeight(45),
decoration: BoxDecoration(
color: Theme.of(context)
.colorScheme
.primaryContainer,
borderRadius:
BorderRadius.circular(15),
boxShadow: [
BoxShadow(
color: Theme.of(context)
.brightness ==
Brightness.dark
? Colors.black
: Colors.grey,
blurRadius: 5,
spreadRadius: 3,
offset: Offset(0, 0))
]),
child: Row(
children: [
Container(
margin: EdgeInsets.symmetric(
horizontal: 25),
height:
getProportionateScreenHeight(
20),
width:
getProportionateScreenWidth(25),
decoration: BoxDecoration(
color: isCorrectAnswer
? Colors.green
: _isUserSelectedAnswer(
int.parse(
dataques.id),
index + 1)
? Colors.red
: Colors.transparent,
borderRadius: BorderRadius.all(
Radius.circular(10)),
border: Border.all(
color: isCorrectAnswer
? Colors.green
: _isUserSelectedAnswer(
int.parse(
dataques
.id),
index + 1)
? Colors.red
: Colors.grey,
width: 2)),
child: Center(
child: isCorrectAnswer
? Icon(
Icons.check,
color: Colors.white,
weight: 5,
)
: _isUserSelectedAnswer(
int.parse(
dataques.id),
index + 1)
? Icon(
Icons.check,
color: Colors.white,
weight: 5,
)
: SizedBox(),
),
),
Text(
' ${_parseHtmlString(dataques.options[index])}',
style: thirdTextStyle.copyWith(
color: isCorrectAnswer
? Colors.green
: _isUserSelectedAnswer(
int.parse(
dataques.id),
index + 1)
? Colors.red
: Colors.grey,
fontSize:
getProportionateScreenWidth(
12)),
),
],
),
),
],
)));
// Helper function to check if the current option is the user's selected answer
},
),
),
// SingleChildScrollView(child: ,),
Padding(
padding: EdgeInsets.only(
bottom: getProportionateScreenHeight(20),
top: getProportionateScreenHeight(10)),
child: Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: EdgeInsets.only(
left: getProportionateScreenWidth(100),
right: getProportionateScreenWidth(100)),
child: DefaultButton(
text: 'Ambil Lagi',
press: () {
setState(() {
fromAmbilLagi = true;
_quizscr(context);
});
},
),
),
),
)
],
),
),
onPopInvoked: (didPop) => _willPop(context),
);
}
void _willPop(BuildContext context) {
Future.delayed(Duration.zero, () {
if (fromAmbilLagi != true) {
Navigator.of(context)..pop();
}
Navigator.of(context)
.pop(); // Hanya pop satu halaman jika tidak dari _quizscr
fromAmbilLagi = false;
});
}
void _quizscr(BuildContext context) {
Navigator.pop(context);
}
}