diff --git a/lib/core/endpoint/api_endpoint.dart b/lib/core/endpoint/api_endpoint.dart index 7b66832..f010423 100644 --- a/lib/core/endpoint/api_endpoint.dart +++ b/lib/core/endpoint/api_endpoint.dart @@ -7,6 +7,8 @@ class APIEndpoint { static const String register = "/register"; static const String quiz = "/quiz"; + static const String quizAnswer = "/quiz/answer"; + static const String userQuiz = "/quiz/user"; static const String quizRecomendation = "/quiz/recomendation"; static const String quizSearch = "/quiz/search"; diff --git a/lib/data/models/answer/answer_model.dart b/lib/data/models/answer/answer_model.dart new file mode 100644 index 0000000..10c2bd6 --- /dev/null +++ b/lib/data/models/answer/answer_model.dart @@ -0,0 +1,31 @@ +class AnswerModel { + final int questionIndex; + final dynamic answer; // String, bool, atau int + final bool isCorrect; + final double timeSpent; + + AnswerModel({ + required this.questionIndex, + required this.answer, + required this.isCorrect, + required this.timeSpent, + }); + + factory AnswerModel.fromJson(Map json) { + return AnswerModel( + questionIndex: json['question_index'], + answer: json['answer'], + isCorrect: json['is_correct'], + timeSpent: (json['time_spent'] as num).toDouble(), + ); + } + + Map toJson() { + return { + 'question_index': questionIndex, + 'answer': answer, + 'is_correct': isCorrect, + 'time_spent': timeSpent, + }; + } +} diff --git a/lib/data/models/answer/quiz_answer_submition_model.dart b/lib/data/models/answer/quiz_answer_submition_model.dart new file mode 100644 index 0000000..980ed7d --- /dev/null +++ b/lib/data/models/answer/quiz_answer_submition_model.dart @@ -0,0 +1,37 @@ +import 'package:quiz_app/data/models/answer/answer_model.dart'; + +class QuizAnswerSubmissionModel { + final String sessionId; + final String quizId; + final String userId; + final DateTime answeredAt; + final List answers; + + QuizAnswerSubmissionModel({ + required this.sessionId, + required this.quizId, + required this.userId, + required this.answeredAt, + required this.answers, + }); + + factory QuizAnswerSubmissionModel.fromJson(Map json) { + return QuizAnswerSubmissionModel( + sessionId: json['session_id'], + quizId: json['quiz_id'], + userId: json['user_id'], + answeredAt: DateTime.parse(json['answered_at']), + answers: (json['answers'] as List).map((e) => AnswerModel.fromJson(e)).toList(), + ); + } + + Map toJson() { + return { + 'session_id': sessionId, + 'quiz_id': quizId, + 'user_id': userId, + 'answered_at': answeredAt.toIso8601String(), + 'answers': answers.map((e) => e.toJson()).toList(), + }; + } +} diff --git a/lib/data/models/quiz/library_quiz_model.dart b/lib/data/models/quiz/library_quiz_model.dart index cc8d7a8..1bae33d 100644 --- a/lib/data/models/quiz/library_quiz_model.dart +++ b/lib/data/models/quiz/library_quiz_model.dart @@ -1,6 +1,7 @@ import 'package:quiz_app/data/models/quiz/question/base_qustion_model.dart'; class QuizData { + final String id; final String authorId; final String subjectId; final String subjectName; @@ -14,6 +15,7 @@ class QuizData { final List questionListings; QuizData({ + required this.id, required this.authorId, required this.subjectId, required this.subjectName, @@ -29,6 +31,7 @@ class QuizData { factory QuizData.fromJson(Map json) { return QuizData( + id: json["id"], authorId: json['author_id'], subjectId: json['subject_id'], subjectName: json['subject_alias'], @@ -45,6 +48,7 @@ class QuizData { Map toJson() { return { + 'id': id, 'author_id': authorId, 'subject_id': subjectId, 'subject_alias': subjectName, diff --git a/lib/data/services/answer_service.dart b/lib/data/services/answer_service.dart index e69de29..e97a9b0 100644 --- a/lib/data/services/answer_service.dart +++ b/lib/data/services/answer_service.dart @@ -0,0 +1,28 @@ +import 'package:dio/dio.dart'; +import 'package:get/get.dart'; +import 'package:quiz_app/core/endpoint/api_endpoint.dart'; +import 'package:quiz_app/core/utils/logger.dart'; +import 'package:quiz_app/data/models/base/base_model.dart'; +import 'package:quiz_app/data/providers/dio_client.dart'; + +class AnswerService extends GetxService { + late final Dio _dio; + + @override + void onInit() { + _dio = Get.find().dio; + super.onInit(); + } + + Future submitQuizAnswers(Map payload) async { + try { + await _dio.post( + APIEndpoint.quizAnswer, + data: payload, + ); + } on DioException catch (e) { + logC.e('Gagal mengirim jawaban: ${e.response?.data['message'] ?? e.message}'); + return null; + } + } +} diff --git a/lib/feature/quiz_play/binding/quiz_play_binding.dart b/lib/feature/quiz_play/binding/quiz_play_binding.dart index 7b3017e..d58c70e 100644 --- a/lib/feature/quiz_play/binding/quiz_play_binding.dart +++ b/lib/feature/quiz_play/binding/quiz_play_binding.dart @@ -1,9 +1,15 @@ import 'package:get/get.dart'; +import 'package:quiz_app/data/controllers/user_controller.dart'; +import 'package:quiz_app/data/services/answer_service.dart'; import 'package:quiz_app/feature/quiz_play/controller/quiz_play_controller.dart'; class QuizPlayBinding extends Bindings { @override void dependencies() { - Get.lazyPut(() => QuizPlayController()); + Get.lazyPut(() => AnswerService()); + Get.lazyPut(() => QuizPlayController( + Get.find(), + Get.find(), + )); } } diff --git a/lib/feature/quiz_play/controller/quiz_play_controller.dart b/lib/feature/quiz_play/controller/quiz_play_controller.dart index a8f02ee..57155d4 100644 --- a/lib/feature/quiz_play/controller/quiz_play_controller.dart +++ b/lib/feature/quiz_play/controller/quiz_play_controller.dart @@ -4,13 +4,21 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:quiz_app/app/routes/app_pages.dart'; import 'package:quiz_app/component/notification/pop_up_confirmation.dart'; +import 'package:quiz_app/data/controllers/user_controller.dart'; +import 'package:quiz_app/data/models/answer/answer_model.dart'; import 'package:quiz_app/data/models/quiz/library_quiz_model.dart'; import 'package:quiz_app/data/models/quiz/question/base_qustion_model.dart'; import 'package:quiz_app/data/models/quiz/question/fill_in_the_blank_question_model.dart'; import 'package:quiz_app/data/models/quiz/question/option_question_model.dart'; import 'package:quiz_app/data/models/quiz/question/true_false_question_model.dart'; +import 'package:quiz_app/data/services/answer_service.dart'; class QuizPlayController extends GetxController { + final AnswerService _answerService; + final UserController _userController; + + QuizPlayController(this._answerService, this._userController); + late final QuizData quizData; // State & UI @@ -152,8 +160,28 @@ class QuizPlayController extends GetxController { AppDialog.showMessage(Get.context!, "Yeay semua soal selesai"); - await Future.delayed(Duration(seconds: 2)); + // Kirim data ke server + try { + await _answerService.submitQuizAnswers({ + "session_id": "", // Sesuaikan logika session ID + "quiz_id": quizData.id, + "user_id": _userController.userData!.id, // Asumsikan ini ada di model `QuizData` + "answered_at": DateTime.now().toIso8601String(), + "answers": answeredQuestions.map((answered) { + return AnswerModel( + questionIndex: answered.questionIndex, + answer: answered.selectedAnswer, + isCorrect: answered.isCorrect, + timeSpent: answered.duration.toDouble(), + ); + }).toList(), + }); + } catch (e) { + AppDialog.showMessage(Get.context!, "Gagal mengirim jawaban: $e"); + return; + } + await Future.delayed(const Duration(seconds: 2)); Get.offAllNamed( AppRoutes.resultQuizPage,