diff --git a/lib/app/routes/app_pages.dart b/lib/app/routes/app_pages.dart index 70bbb1c..41296f7 100644 --- a/lib/app/routes/app_pages.dart +++ b/lib/app/routes/app_pages.dart @@ -3,7 +3,9 @@ import 'package:quiz_app/app/middleware/auth_middleware.dart'; import 'package:quiz_app/feature/history/binding/history_binding.dart'; import 'package:quiz_app/feature/home/binding/home_binding.dart'; import 'package:quiz_app/feature/home/view/home_page.dart'; +import 'package:quiz_app/feature/library/binding/detail_quiz_binding.dart'; import 'package:quiz_app/feature/library/binding/library_binding.dart'; +import 'package:quiz_app/feature/library/view/detail_quix_view.dart'; import 'package:quiz_app/feature/login/bindings/login_binding.dart'; import 'package:quiz_app/feature/login/view/login_page.dart'; import 'package:quiz_app/feature/navigation/bindings/navigation_binding.dart'; @@ -65,5 +67,10 @@ class AppPages { page: () => QuizPreviewPage(), binding: QuizPreviewBinding(), ), + GetPage( + name: AppRoutes.detailQuizPage, + page: () => DetailQuizView(), + binding: DetailQuizBinding(), + ) ]; } diff --git a/lib/app/routes/app_routes.dart b/lib/app/routes/app_routes.dart index e1f43d9..8f896b1 100644 --- a/lib/app/routes/app_routes.dart +++ b/lib/app/routes/app_routes.dart @@ -10,4 +10,6 @@ abstract class AppRoutes { static const quizCreatePage = "/quiz/creation"; static const quizPreviewPage = "/quiz/preview"; + + static const detailQuizPage = "/quiz/detail"; } diff --git a/lib/data/models/quiz/library_quiz_model.dart b/lib/data/models/quiz/library_quiz_model.dart index 8dc601e..e60214c 100644 --- a/lib/data/models/quiz/library_quiz_model.dart +++ b/lib/data/models/quiz/library_quiz_model.dart @@ -1,3 +1,5 @@ +import 'package:quiz_app/data/models/quiz/question_listings_model.dart'; + class QuizData { final String authorId; final String title; @@ -45,39 +47,3 @@ class QuizData { }; } } - -class QuestionListing { - final String question; - final String targetAnswer; - final int duration; - final String type; - final List? options; - - QuestionListing({ - required this.question, - required this.targetAnswer, - required this.duration, - required this.type, - this.options, - }); - - factory QuestionListing.fromJson(Map json) { - return QuestionListing( - question: json['question'], - targetAnswer: json['target_answer'], - duration: json['duration'], - type: json['type'], - options: json['options'] != null ? List.from(json['options']) : null, - ); - } - - Map toJson() { - return { - 'question': question, - 'target_answer': targetAnswer, - 'duration': duration, - 'type': type, - 'options': options, - }; - } -} diff --git a/lib/data/models/quiz/question_create_request.dart b/lib/data/models/quiz/question_create_request.dart index b535fe2..d5d0e34 100644 --- a/lib/data/models/quiz/question_create_request.dart +++ b/lib/data/models/quiz/question_create_request.dart @@ -1,3 +1,5 @@ +import 'package:quiz_app/data/models/quiz/question_listings_model.dart'; + class QuizCreateRequestModel { final String title; final String description; @@ -33,33 +35,33 @@ class QuizCreateRequestModel { } } -class QuestionListing { - final String question; - final String targetAnswer; - final int duration; - final String type; - final List? options; +// class QuestionListing { +// final String question; +// final String targetAnswer; +// final int duration; +// final String type; +// final List? options; - QuestionListing({ - required this.question, - required this.targetAnswer, - required this.duration, - required this.type, - this.options, - }); +// QuestionListing({ +// required this.question, +// required this.targetAnswer, +// required this.duration, +// required this.type, +// this.options, +// }); - Map toJson() { - final map = { - 'question': question, - 'target_answer': targetAnswer, - 'duration': duration, - 'type': type, - }; +// Map toJson() { +// final map = { +// 'question': question, +// 'target_answer': targetAnswer, +// 'duration': duration, +// 'type': type, +// }; - if (options != null && options!.isNotEmpty) { - map['options'] = options; - } +// if (options != null && options!.isNotEmpty) { +// map['options'] = options; +// } - return map; - } -} +// return map; +// } +// } diff --git a/lib/data/models/quiz/question_listings_model.dart b/lib/data/models/quiz/question_listings_model.dart new file mode 100644 index 0000000..0c5a331 --- /dev/null +++ b/lib/data/models/quiz/question_listings_model.dart @@ -0,0 +1,35 @@ +class QuestionListing { + final String question; + final String targetAnswer; + final int duration; + final String type; + final List? options; + + QuestionListing({ + required this.question, + required this.targetAnswer, + required this.duration, + required this.type, + this.options, + }); + + factory QuestionListing.fromJson(Map json) { + return QuestionListing( + question: json['question'], + targetAnswer: json['target_answer'], + duration: json['duration'], + type: json['type'], + options: json['options'] != null ? List.from(json['options']) : null, + ); + } + + Map toJson() { + return { + 'question': question, + 'target_answer': targetAnswer, + 'duration': duration, + 'type': type, + 'options': options, + }; + } +} diff --git a/lib/feature/library/binding/detail_quiz_binding.dart b/lib/feature/library/binding/detail_quiz_binding.dart new file mode 100644 index 0000000..684c18c --- /dev/null +++ b/lib/feature/library/binding/detail_quiz_binding.dart @@ -0,0 +1,9 @@ +import 'package:get/get.dart'; +import 'package:quiz_app/feature/library/controller/detail_quiz_controller.dart'; + +class DetailQuizBinding extends Bindings { + @override + void dependencies() { + Get.lazyPut(() => DetailQuizController()); + } +} diff --git a/lib/feature/library/controller/detail_quiz_controller.dart b/lib/feature/library/controller/detail_quiz_controller.dart index 25856c3..34db30c 100644 --- a/lib/feature/library/controller/detail_quiz_controller.dart +++ b/lib/feature/library/controller/detail_quiz_controller.dart @@ -1,72 +1,15 @@ import 'package:get/get.dart'; +import 'package:quiz_app/data/models/quiz/library_quiz_model.dart'; class DetailQuizController extends GetxController { - Rx quizData = QuizDetailData( - title: "Sejarah Indonesia - Kerajaan Hindu Budha", - description: "Kuis ini membahas kerajaan-kerajaan Hindu Budha di Indonesia seperti Kutai, Sriwijaya, dan Majapahit.", - date: DateTime.parse("2025-04-25 10:00:00"), - isPublic: true, - totalQuiz: 3, - limitDuration: 900, // dalam detik (900 = 15 menit) - questionListings: [ - QuestionListing( - question: "Kerajaan Hindu tertua di Indonesia adalah?", - targetAnswer: "Kutai", - duration: 30, - type: "fill_the_blank", - ), - QuestionListing( - question: "Apakah benar Majapahit mencapai puncak kejayaan pada masa Hayam Wuruk?", - targetAnswer: "Ya", - duration: 30, - type: "true_false", - ), - QuestionListing( - question: "Kerajaan maritim terbesar di Asia Tenggara pada abad ke-7 adalah?", - targetAnswer: "Sriwijaya", - duration: 30, - type: "fill_the_blank", - ), - ], - ).obs; - + late QuizData data; @override void onInit() { + loadData(); super.onInit(); - // Dummy data sudah di-inject saat controller init + } + + void loadData() { + data = Get.arguments as QuizData; } } - -class QuizDetailData { - String title; - String description; - DateTime date; - bool isPublic; - int totalQuiz; - int limitDuration; - List questionListings; - - QuizDetailData({ - this.title = '', - this.description = '', - required this.date, - this.isPublic = true, - this.totalQuiz = 0, - this.limitDuration = 0, - this.questionListings = const [], - }); -} - -class QuestionListing { - String question; - String targetAnswer; - int duration; - String type; - - QuestionListing({ - required this.question, - required this.targetAnswer, - required this.duration, - required this.type, - }); -} diff --git a/lib/feature/library/controller/library_controller.dart b/lib/feature/library/controller/library_controller.dart index bf24873..93d0da5 100644 --- a/lib/feature/library/controller/library_controller.dart +++ b/lib/feature/library/controller/library_controller.dart @@ -1,4 +1,5 @@ import 'package:get/get.dart'; +import 'package:quiz_app/app/routes/app_pages.dart'; import 'package:quiz_app/data/controllers/user_controller.dart'; import 'package:quiz_app/data/models/quiz/library_quiz_model.dart'; import 'package:quiz_app/data/services/quiz_service.dart'; @@ -36,6 +37,10 @@ class LibraryController extends GetxController { } } + void goToDetail(int index) { + Get.toNamed(AppRoutes.detailQuizPage, arguments: quizs[index]); + } + String formatDuration(int seconds) { int minutes = seconds ~/ 60; return '$minutes menit'; diff --git a/lib/feature/library/view/detail_quix_view.dart b/lib/feature/library/view/detail_quix_view.dart index 57f8578..36055a5 100644 --- a/lib/feature/library/view/detail_quix_view.dart +++ b/lib/feature/library/view/detail_quix_view.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:quiz_app/app/const/colors/app_colors.dart'; +import 'package:quiz_app/component/global_button.dart'; +import 'package:quiz_app/data/models/quiz/question_listings_model.dart'; import 'package:quiz_app/feature/library/controller/detail_quiz_controller.dart'; class DetailQuizView extends GetView { @@ -8,8 +10,6 @@ class DetailQuizView extends GetView { @override Widget build(BuildContext context) { - final data = controller.quizData.value; - return Scaffold( backgroundColor: AppColors.background, appBar: AppBar( @@ -34,7 +34,7 @@ class DetailQuizView extends GetView { children: [ // Header Section Text( - data.title, + controller.data.title, style: const TextStyle( fontSize: 22, fontWeight: FontWeight.bold, @@ -43,7 +43,7 @@ class DetailQuizView extends GetView { ), const SizedBox(height: 8), Text( - data.description, + controller.data.description ?? "", style: const TextStyle( fontSize: 14, color: AppColors.softGrayText, @@ -55,29 +55,35 @@ class DetailQuizView extends GetView { const Icon(Icons.calendar_today_rounded, size: 16, color: AppColors.softGrayText), const SizedBox(width: 6), Text( - _formatDate(data.date), + controller.data.date ?? "", style: const TextStyle(fontSize: 12, color: AppColors.softGrayText), ), const SizedBox(width: 12), const Icon(Icons.timer_rounded, size: 16, color: AppColors.softGrayText), const SizedBox(width: 6), Text( - '${data.limitDuration ~/ 60} menit', + '${controller.data.limitDuration ~/ 60} menit', style: const TextStyle(fontSize: 12, color: AppColors.softGrayText), ), ], ), const SizedBox(height: 20), - const Divider(thickness: 1.2, color: AppColors.borderLight), const SizedBox(height: 20), + GlobalButton(text: "Kerjakan", onPressed: () {}), + const SizedBox(height: 20), + GlobalButton(text: "buat ruangan", onPressed: () {}), + + const SizedBox(height: 20), + const Divider(thickness: 1.2, color: AppColors.borderLight), + const SizedBox(height: 20), // Soal Section ListView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), - itemCount: data.questionListings.length, + itemCount: controller.data.questionListings.length, itemBuilder: (context, index) { - final question = data.questionListings[index]; + final question = controller.data.questionListings[index]; return _buildQuestionItem(question, index + 1); }, ), @@ -134,14 +140,14 @@ class DetailQuizView extends GetView { color: AppColors.darkText, ), ), - const SizedBox(height: 12), - Text( - 'Jawaban: ${question.targetAnswer}', - style: const TextStyle( - fontSize: 14, - color: AppColors.softGrayText, - ), - ), + // const SizedBox(height: 12), + // Text( + // 'Jawaban: ${question.targetAnswer}', + // style: const TextStyle( + // fontSize: 14, + // color: AppColors.softGrayText, + // ), + // ), const SizedBox(height: 8), Text( 'Durasi: ${question.duration} detik', @@ -167,8 +173,4 @@ class DetailQuizView extends GetView { return 'Tipe Tidak Diketahui'; } } - - String _formatDate(DateTime date) { - return '${date.day}/${date.month}/${date.year}'; - } } diff --git a/lib/feature/library/view/library_view.dart b/lib/feature/library/view/library_view.dart index 11c8da3..7f574c6 100644 --- a/lib/feature/library/view/library_view.dart +++ b/lib/feature/library/view/library_view.dart @@ -64,7 +64,7 @@ class LibraryView extends GetView { itemCount: controller.quizs.length, itemBuilder: (context, index) { final quiz = controller.quizs[index]; - return _buildQuizCard(quiz); + return InkWell(onTap: () => controller.goToDetail(index), child: _buildQuizCard(quiz)); }, ); }), diff --git a/lib/feature/quiz_preview/controller/quiz_preview_controller.dart b/lib/feature/quiz_preview/controller/quiz_preview_controller.dart index 37d16b9..a357183 100644 --- a/lib/feature/quiz_preview/controller/quiz_preview_controller.dart +++ b/lib/feature/quiz_preview/controller/quiz_preview_controller.dart @@ -6,6 +6,7 @@ import 'package:quiz_app/app/routes/app_pages.dart'; import 'package:quiz_app/core/utils/logger.dart'; import 'package:quiz_app/data/controllers/user_controller.dart'; import 'package:quiz_app/data/models/quiz/question_create_request.dart'; +import 'package:quiz_app/data/models/quiz/question_listings_model.dart'; import 'package:quiz_app/data/models/quiz/quiestion_data_model.dart'; import 'package:quiz_app/data/services/quiz_service.dart';