fix: navigation on the quiz multiplayer and the result page
This commit is contained in:
parent
abe21031ec
commit
15e4a9295c
|
@ -35,6 +35,11 @@ class AdminResultController extends GetxController {
|
|||
|
||||
void goToDetailParticipants(String userId, String username) => Get.toNamed(
|
||||
AppRoutes.quizMPLResultPage,
|
||||
arguments: {"user_id": userId, "session_id": sessionId, "username": username},
|
||||
arguments: {
|
||||
"user_id": userId,
|
||||
"session_id": sessionId,
|
||||
"username": username,
|
||||
"is_admin": true,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import 'dart:convert';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:quiz_app/app/routes/app_pages.dart';
|
||||
import 'package:quiz_app/data/models/history/participant_history_result.dart';
|
||||
import 'package:quiz_app/data/services/answer_service.dart';
|
||||
|
||||
|
@ -12,6 +12,7 @@ class ParticipantResultController extends GetxController {
|
|||
final RxBool isLoading = false.obs;
|
||||
|
||||
RxString participantName = "".obs;
|
||||
bool isAdmin = false;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
|
@ -24,6 +25,7 @@ class ParticipantResultController extends GetxController {
|
|||
|
||||
final args = Get.arguments;
|
||||
participantName.value = args["username"];
|
||||
isAdmin = args["is_admin"];
|
||||
final response = await _answerService.getAnswerSession(args["session_id"], args["user_id"]);
|
||||
|
||||
if (response != null) {
|
||||
|
@ -44,4 +46,20 @@ class ParticipantResultController extends GetxController {
|
|||
int getTotalQuestions() {
|
||||
return participantResult.value?.totalQuestions ?? 0;
|
||||
}
|
||||
|
||||
void goBackPage() {
|
||||
if (isAdmin) {
|
||||
Get.back();
|
||||
} else {
|
||||
Get.offAllNamed(AppRoutes.mainPage);
|
||||
}
|
||||
}
|
||||
|
||||
void onPop(bool isPop, dynamic value) {
|
||||
if (isAdmin) {
|
||||
Get.back();
|
||||
} else {
|
||||
Get.offAllNamed(AppRoutes.mainPage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,43 +12,63 @@ class ParticipantDetailPage extends GetView<ParticipantResultController> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: AppColors.background,
|
||||
appBar: AppBar(
|
||||
title: const Text('Detail Peserta'),
|
||||
backgroundColor: Colors.white,
|
||||
foregroundColor: AppColors.darkText,
|
||||
elevation: 0,
|
||||
leading: IconButton(
|
||||
icon: const Icon(LucideIcons.arrowLeft),
|
||||
onPressed: () => Get.back(),
|
||||
),
|
||||
),
|
||||
body: Obx(() {
|
||||
if (controller.isLoading.value) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
return PopScope(
|
||||
canPop: false,
|
||||
onPopInvokedWithResult: controller.onPop,
|
||||
child: Scaffold(
|
||||
backgroundColor: AppColors.background,
|
||||
body: Obx(() {
|
||||
if (controller.isLoading.value) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
|
||||
final participant = controller.participantResult.value;
|
||||
if (participant == null) {
|
||||
return const Center(child: Text('Data peserta tidak tersedia.'));
|
||||
}
|
||||
final participant = controller.participantResult.value;
|
||||
if (participant == null) {
|
||||
return const Center(child: Text('Data peserta tidak tersedia.'));
|
||||
}
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
_buildParticipantHeader(participant),
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
padding: const EdgeInsets.all(16),
|
||||
itemCount: participant.answers.length,
|
||||
itemBuilder: (context, index) {
|
||||
return _buildAnswerCard(participant.answers[index], index + 1);
|
||||
},
|
||||
),
|
||||
return SafeArea(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
color: Colors.white,
|
||||
child: Row(
|
||||
children: [
|
||||
IconButton(
|
||||
icon: const Icon(LucideIcons.arrowLeft),
|
||||
color: AppColors.darkText,
|
||||
onPressed: controller.goBackPage,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
const Text(
|
||||
'Detail Peserta',
|
||||
style: TextStyle(
|
||||
color: AppColors.darkText,
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// Body Content
|
||||
_buildParticipantHeader(participant),
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
padding: const EdgeInsets.all(16),
|
||||
itemCount: participant.answers.length,
|
||||
itemBuilder: (context, index) {
|
||||
return _buildAnswerCard(participant.answers[index], index + 1);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}),
|
||||
);
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,42 +11,45 @@ class MonitorQuizView extends GetView<MonitorQuizController> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: AppColors.background,
|
||||
body: SafeArea(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_buildSectionHeader("Monitor Admin"),
|
||||
Obx(() => _buildCurrentQuestion(
|
||||
questionText: controller.currentQuestion.value,
|
||||
)),
|
||||
const SizedBox(height: 24),
|
||||
_buildSectionHeader('Daftar Peserta'),
|
||||
const SizedBox(height: 16),
|
||||
Expanded(
|
||||
child: Obx(
|
||||
() => ListView.separated(
|
||||
itemCount: controller.participan.length,
|
||||
separatorBuilder: (context, index) => const SizedBox(height: 12),
|
||||
itemBuilder: (context, index) {
|
||||
final student = controller.participan[index];
|
||||
final totalAnswers = student.correct.value + student.wrong.value;
|
||||
final progressPercent = totalAnswers > 0 ? student.correct.value / totalAnswers : 0.0;
|
||||
return PopScope(
|
||||
canPop: false,
|
||||
child: Scaffold(
|
||||
backgroundColor: AppColors.background,
|
||||
body: SafeArea(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_buildSectionHeader("Monitor Admin"),
|
||||
Obx(() => _buildCurrentQuestion(
|
||||
questionText: controller.currentQuestion.value,
|
||||
)),
|
||||
const SizedBox(height: 24),
|
||||
_buildSectionHeader('Daftar Peserta'),
|
||||
const SizedBox(height: 16),
|
||||
Expanded(
|
||||
child: Obx(
|
||||
() => ListView.separated(
|
||||
itemCount: controller.participan.length,
|
||||
separatorBuilder: (context, index) => const SizedBox(height: 12),
|
||||
itemBuilder: (context, index) {
|
||||
final student = controller.participan[index];
|
||||
final totalAnswers = student.correct.value + student.wrong.value;
|
||||
final progressPercent = totalAnswers > 0 ? student.correct.value / totalAnswers : 0.0;
|
||||
|
||||
return _buildStudentCard(
|
||||
name: student.name,
|
||||
totalBenar: student.correct.value,
|
||||
totalSalah: student.wrong.value,
|
||||
progressPercent: progressPercent,
|
||||
);
|
||||
},
|
||||
return _buildStudentCard(
|
||||
name: student.name,
|
||||
totalBenar: student.correct.value,
|
||||
totalSalah: student.wrong.value,
|
||||
progressPercent: progressPercent,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'dart:async';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:quiz_app/app/routes/app_pages.dart';
|
||||
import 'package:quiz_app/component/global_button.dart';
|
||||
import 'package:quiz_app/data/controllers/user_controller.dart';
|
||||
import 'package:quiz_app/data/services/socket_service.dart';
|
||||
|
@ -129,10 +130,19 @@ class PlayQuizMultiplayerController extends GetxController {
|
|||
}
|
||||
}
|
||||
|
||||
void goToDetailResult() {
|
||||
Get.offAllNamed(AppRoutes.quizMPLResultPage, arguments: {
|
||||
"user_id": _userController.userData!.id,
|
||||
"session_id": sessionId,
|
||||
"username": _userController.userName.value,
|
||||
"is_admin": false,
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
fillInAnswerController.dispose();
|
||||
_cancelTimer(); // Important: cancel timer when controller is closed
|
||||
_cancelTimer();
|
||||
super.onClose();
|
||||
}
|
||||
}
|
||||
|
@ -140,7 +150,7 @@ class PlayQuizMultiplayerController extends GetxController {
|
|||
class MultiplayerQuestionModel {
|
||||
final int questionIndex;
|
||||
final String question;
|
||||
final String type; // 'option', 'true_false', 'fill_in_the_blank'
|
||||
final String type;
|
||||
final int duration;
|
||||
final List<String>? options;
|
||||
|
||||
|
|
|
@ -7,19 +7,22 @@ import 'package:quiz_app/feature/play_quiz_multiplayer/controller/play_quiz_cont
|
|||
class PlayQuizMultiplayerView extends GetView<PlayQuizMultiplayerController> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: const Color(0xFFF9FAFB),
|
||||
body: Obx(() {
|
||||
if (controller.isDone.value) {
|
||||
return _buildDoneView();
|
||||
}
|
||||
return PopScope(
|
||||
canPop: false,
|
||||
child: Scaffold(
|
||||
backgroundColor: const Color(0xFFF9FAFB),
|
||||
body: Obx(() {
|
||||
if (controller.isDone.value) {
|
||||
return _buildDoneView();
|
||||
}
|
||||
|
||||
if (controller.currentQuestion.value == null) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
if (controller.currentQuestion.value == null) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
|
||||
return _buildQuestionView();
|
||||
}),
|
||||
return _buildQuestionView();
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -245,10 +248,7 @@ class PlayQuizMultiplayerView extends GetView<PlayQuizMultiplayerController> {
|
|||
),
|
||||
const SizedBox(height: 40),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
// Arahkan ke halaman hasil atau leaderboard
|
||||
Get.back();
|
||||
},
|
||||
onPressed: controller.goToDetailResult,
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: const Color(0xFF2563EB),
|
||||
foregroundColor: Colors.white,
|
||||
|
|
Loading…
Reference in New Issue