feat: adding create automatic quiz
This commit is contained in:
parent
737f0f775a
commit
d925a22bb0
|
@ -82,5 +82,7 @@
|
|||
"save_quiz": "Save Quiz",
|
||||
|
||||
"select_language": "Select Language",
|
||||
"change_language": "Change Language"
|
||||
"change_language": "Change Language",
|
||||
|
||||
"auto_generate_quiz": "Auto Generate Quiz"
|
||||
}
|
||||
|
|
|
@ -82,5 +82,6 @@
|
|||
"save_quiz": "Simpan Kuis",
|
||||
|
||||
"select_language": "Pilih Bahasa",
|
||||
"change_language": "Ganti Bahasa"
|
||||
"change_language": "Ganti Bahasa",
|
||||
"auto_generate_quiz": "Buat Kuis Otomatis"
|
||||
}
|
||||
|
|
|
@ -79,5 +79,7 @@
|
|||
"quiz_description_label": "Deskripsi Ringkas",
|
||||
"quiz_subject_label": "Subjek",
|
||||
"make_quiz_public": "Jadikan Kuiz Umum",
|
||||
"save_quiz": "Simpan Kuiz"
|
||||
"save_quiz": "Simpan Kuiz",
|
||||
|
||||
"auto_generate_quiz": "Jana Kuiz Automatik"
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ class MyApp extends StatelessWidget {
|
|||
localizationsDelegates: context.localizationDelegates,
|
||||
supportedLocales: context.supportedLocales,
|
||||
initialBinding: InitialBindings(),
|
||||
initialRoute: AppRoutes.monitorResultMPLPage,
|
||||
initialRoute: AppRoutes.splashScreen,
|
||||
getPages: AppPages.routes,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -37,7 +37,6 @@ import 'package:quiz_app/feature/search/binding/search_binding.dart';
|
|||
import 'package:quiz_app/feature/splash_screen/presentation/splash_screen_page.dart';
|
||||
import 'package:quiz_app/feature/waiting_room/binding/waiting_room_binding.dart';
|
||||
import 'package:quiz_app/feature/waiting_room/view/waiting_room_view.dart';
|
||||
import 'package:quiz_app/feature/admin_result_page/view/admin_result_page.dart';
|
||||
|
||||
part 'app_routes.dart';
|
||||
|
||||
|
@ -136,9 +135,9 @@ class AppPages {
|
|||
page: () => PlayQuizMultiplayerView(),
|
||||
binding: PlayQuizMultiplayerBinding(),
|
||||
),
|
||||
GetPage(
|
||||
name: AppRoutes.monitorResultMPLPage,
|
||||
page: () => AdminResultPage(),
|
||||
)
|
||||
// GetPage(
|
||||
// name: AppRoutes.monitorResultMPLPage,
|
||||
// page: () => AdminResultPage(),
|
||||
// )
|
||||
];
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ class APIEndpoint {
|
|||
static const String register = "/register";
|
||||
|
||||
static const String quiz = "/quiz";
|
||||
static const String quizGenerate = "/quiz/ai";
|
||||
static const String quizAnswer = "/quiz/answer";
|
||||
|
||||
static const String userQuiz = "/quiz/user";
|
||||
|
|
|
@ -35,6 +35,32 @@ class QuizService extends GetxService {
|
|||
}
|
||||
}
|
||||
|
||||
Future<BaseResponseModel<List<RawQuizModel>>> createQuizAuto(String sentence) async {
|
||||
try {
|
||||
final response = await _dio.post(
|
||||
APIEndpoint.quizGenerate,
|
||||
data: {"sentence": sentence},
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
print(response.data);
|
||||
|
||||
// Parsing response using BaseResponseModel
|
||||
final parseResponse = BaseResponseModel<List<RawQuizModel>>.fromJson(
|
||||
response.data,
|
||||
(data) => (data as List).map((item) => RawQuizModel.fromJson(item as Map<String, dynamic>)).toList(),
|
||||
);
|
||||
|
||||
return parseResponse;
|
||||
} else {
|
||||
throw Exception("Quiz creation failed with status: ${response.statusCode}");
|
||||
}
|
||||
} catch (e) {
|
||||
logC.e("Quiz creation error: $e");
|
||||
throw Exception("Quiz creation error: $e");
|
||||
}
|
||||
}
|
||||
|
||||
Future<BaseResponseModel<List<QuizListingModel>>?> userQuiz(String userId, int page) async {
|
||||
try {
|
||||
final response = await _dio.get("${APIEndpoint.userQuiz}/$userId?page=$page");
|
||||
|
@ -122,3 +148,27 @@ class QuizService extends GetxService {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
class RawQuizModel {
|
||||
final String qustion;
|
||||
final dynamic answer;
|
||||
|
||||
RawQuizModel({
|
||||
required this.qustion,
|
||||
required this.answer,
|
||||
});
|
||||
|
||||
factory RawQuizModel.fromJson(Map<String, dynamic> json) {
|
||||
return RawQuizModel(
|
||||
qustion: json['qustion'] as String,
|
||||
answer: json['answer'],
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'qustion': qustion,
|
||||
'answer': answer,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
import "package:get/get.dart";
|
||||
import "package:quiz_app/data/services/quiz_service.dart";
|
||||
import "package:quiz_app/feature/quiz_creation/controller/quiz_creation_controller.dart";
|
||||
|
||||
class QuizCreationBinding extends Bindings {
|
||||
@override
|
||||
void dependencies() {
|
||||
Get.lazyPut<QuizCreationController>(() => QuizCreationController());
|
||||
Get.lazyPut(() => QuizService());
|
||||
Get.lazyPut<QuizCreationController>(
|
||||
() => QuizCreationController(
|
||||
Get.find<QuizService>(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,9 +5,18 @@ import 'package:quiz_app/app/const/enums/question_type.dart';
|
|||
import 'package:quiz_app/app/routes/app_pages.dart';
|
||||
import 'package:quiz_app/component/notification/delete_confirmation.dart';
|
||||
import 'package:quiz_app/component/notification/pop_up_confirmation.dart';
|
||||
import 'package:quiz_app/core/utils/custom_floating_loading.dart';
|
||||
import 'package:quiz_app/core/utils/logger.dart';
|
||||
import 'package:quiz_app/data/models/base/base_model.dart';
|
||||
import 'package:quiz_app/data/models/quiz/quiestion_data_model.dart';
|
||||
import 'package:quiz_app/data/services/quiz_service.dart';
|
||||
|
||||
class QuizCreationController extends GetxController {
|
||||
final QuizService _quizService;
|
||||
|
||||
QuizCreationController(this._quizService);
|
||||
|
||||
final TextEditingController inputSentenceTC = TextEditingController();
|
||||
final TextEditingController questionTC = TextEditingController();
|
||||
final TextEditingController answerTC = TextEditingController();
|
||||
final List<TextEditingController> optionTCList = List.generate(4, (_) => TextEditingController());
|
||||
|
@ -213,4 +222,56 @@ class QuizCreationController extends GetxController {
|
|||
selectedQuizIndex.value -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
void generateQuiz() async {
|
||||
CustomFloatingLoading.showLoadingDialog(Get.context!);
|
||||
|
||||
try {
|
||||
BaseResponseModel<List<RawQuizModel>> response = await _quizService.createQuizAuto(inputSentenceTC.text);
|
||||
|
||||
if (response.data != null) {
|
||||
final previousLength = quizData.length;
|
||||
|
||||
if (previousLength == 1) quizData.removeAt(0);
|
||||
|
||||
for (final i in response.data!) {
|
||||
QuestionType type = QuestionType.fillTheBlank;
|
||||
|
||||
if (i.answer.toString().toLowerCase() == 'true' || i.answer.toString().toLowerCase() == 'false') {
|
||||
type = QuestionType.trueOrFalse;
|
||||
}
|
||||
|
||||
quizData.add(QuestionData(
|
||||
index: quizData.length + 1,
|
||||
question: i.qustion,
|
||||
answer: i.answer,
|
||||
type: type,
|
||||
));
|
||||
}
|
||||
|
||||
if (response.data!.isNotEmpty) {
|
||||
selectedQuizIndex.value = previousLength;
|
||||
final data = quizData[selectedQuizIndex.value];
|
||||
questionTC.text = data.question ?? "";
|
||||
answerTC.text = data.answer ?? "";
|
||||
currentDuration.value = data.duration;
|
||||
currentQuestionType.value = data.type ?? QuestionType.fillTheBlank;
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
logC.e("Error while generating quiz: $e");
|
||||
} finally {
|
||||
CustomFloatingLoading.hideLoadingDialog(Get.context!);
|
||||
isGenerate.value = false;
|
||||
|
||||
if (quizData.isNotEmpty && selectedQuizIndex.value == 0) {
|
||||
final data = quizData[0];
|
||||
questionTC.text = data.question ?? "";
|
||||
answerTC.text = data.answer ?? "";
|
||||
currentDuration.value = data.duration;
|
||||
currentQuestionType.value = data.type ?? QuestionType.fillTheBlank;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:quiz_app/app/const/colors/app_colors.dart';
|
||||
import 'package:quiz_app/app/const/enums/question_type.dart';
|
||||
import 'package:quiz_app/component/global_button.dart';
|
||||
import 'package:quiz_app/feature/quiz_creation/controller/quiz_creation_controller.dart';
|
||||
import 'package:quiz_app/feature/quiz_creation/view/component/fill_the_blank_component.dart';
|
||||
import 'package:quiz_app/feature/quiz_creation/view/component/option_question_component.dart';
|
||||
|
@ -30,6 +32,11 @@ class CustomQuestionComponent extends GetView<QuizCreationController> {
|
|||
_questionTypeValue(),
|
||||
const SizedBox(height: 20),
|
||||
_buildDurationDropdown(),
|
||||
const SizedBox(height: 30),
|
||||
GlobalButton(
|
||||
text: context.tr('save_all'),
|
||||
onPressed: controller.onDone,
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:quiz_app/component/global_button.dart';
|
||||
import 'package:quiz_app/component/global_text_field.dart';
|
||||
import 'package:quiz_app/feature/quiz_creation/controller/quiz_creation_controller.dart';
|
||||
|
||||
class GenerateComponent extends GetView<QuizCreationController> {
|
||||
const GenerateComponent({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
"Unggah file materi kamu (PDF atau Word) untuk membuat soal otomatis.",
|
||||
"Masukkan paragraf untuk dijadikan soal",
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Color(0xFF6B778C),
|
||||
|
@ -19,41 +21,16 @@ class GenerateComponent extends GetView<QuizCreationController> {
|
|||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
GestureDetector(
|
||||
onTap: () {},
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.symmetric(vertical: 30),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFF0F2F5),
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
border: Border.all(color: Colors.grey.shade300),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: const [
|
||||
Icon(Icons.insert_drive_file, size: 50, color: Color(0xFF6B778C)),
|
||||
SizedBox(height: 10),
|
||||
Text(
|
||||
"Upload PDF atau Word",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
color: Color(0xFF6B778C),
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
Text(
|
||||
"Max 10 MB",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Color(0xFF9FA8B2),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
GlobalTextField(
|
||||
hintText: "Tulis kalimat atau paragraf panjang, dan kami akan mengubahnya menjadi soal secara otomatis",
|
||||
controller: controller.inputSentenceTC,
|
||||
limitTextLine: 15,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
GlobalButton(
|
||||
text: context.tr('auto_generate_quiz'),
|
||||
onPressed: controller.generateQuiz,
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
|
|||
import 'package:get/get.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:quiz_app/app/const/colors/app_colors.dart';
|
||||
import 'package:quiz_app/component/global_button.dart';
|
||||
import 'package:quiz_app/feature/quiz_creation/controller/quiz_creation_controller.dart';
|
||||
import 'package:quiz_app/feature/quiz_creation/view/component/custom_question_component.dart';
|
||||
import 'package:quiz_app/feature/quiz_creation/view/component/generate_component.dart';
|
||||
|
@ -40,11 +39,6 @@ class QuizCreationView extends GetView<QuizCreationController> {
|
|||
_buildModeSelector(context),
|
||||
const SizedBox(height: 20),
|
||||
Obx(() => controller.isGenerate.value ? const GenerateComponent() : const CustomQuestionComponent()),
|
||||
const SizedBox(height: 30),
|
||||
GlobalButton(
|
||||
text: context.tr('save_all'),
|
||||
onPressed: controller.onDone,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
Loading…
Reference in New Issue