501 lines
24 KiB
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"<[^>]*>| ", 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);
|
|
}
|
|
}
|