Initial commit: Penyerahan final Source code Tugas Akhir
This commit is contained in:
500
lib/screens/course/quiz_result_page.dart
Normal file
500
lib/screens/course/quiz_result_page.dart
Normal file
@ -0,0 +1,500 @@
|
||||
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);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user