fix: navigation on the quiz multiplayer and the result page

This commit is contained in:
akhdanre 2025-05-19 02:09:30 +07:00
parent abe21031ec
commit 15e4a9295c
6 changed files with 142 additions and 86 deletions

View File

@ -35,6 +35,11 @@ class AdminResultController extends GetxController {
void goToDetailParticipants(String userId, String username) => Get.toNamed( void goToDetailParticipants(String userId, String username) => Get.toNamed(
AppRoutes.quizMPLResultPage, AppRoutes.quizMPLResultPage,
arguments: {"user_id": userId, "session_id": sessionId, "username": username}, arguments: {
"user_id": userId,
"session_id": sessionId,
"username": username,
"is_admin": true,
},
); );
} }

View File

@ -1,5 +1,5 @@
import 'dart:convert';
import 'package:get/get.dart'; 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/models/history/participant_history_result.dart';
import 'package:quiz_app/data/services/answer_service.dart'; import 'package:quiz_app/data/services/answer_service.dart';
@ -12,6 +12,7 @@ class ParticipantResultController extends GetxController {
final RxBool isLoading = false.obs; final RxBool isLoading = false.obs;
RxString participantName = "".obs; RxString participantName = "".obs;
bool isAdmin = false;
@override @override
void onInit() { void onInit() {
@ -24,6 +25,7 @@ class ParticipantResultController extends GetxController {
final args = Get.arguments; final args = Get.arguments;
participantName.value = args["username"]; participantName.value = args["username"];
isAdmin = args["is_admin"];
final response = await _answerService.getAnswerSession(args["session_id"], args["user_id"]); final response = await _answerService.getAnswerSession(args["session_id"], args["user_id"]);
if (response != null) { if (response != null) {
@ -44,4 +46,20 @@ class ParticipantResultController extends GetxController {
int getTotalQuestions() { int getTotalQuestions() {
return participantResult.value?.totalQuestions ?? 0; 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);
}
}
} }

View File

@ -12,18 +12,11 @@ class ParticipantDetailPage extends GetView<ParticipantResultController> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return PopScope(
canPop: false,
onPopInvokedWithResult: controller.onPop,
child: Scaffold(
backgroundColor: AppColors.background, 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(() { body: Obx(() {
if (controller.isLoading.value) { if (controller.isLoading.value) {
return const Center(child: CircularProgressIndicator()); return const Center(child: CircularProgressIndicator());
@ -34,8 +27,33 @@ class ParticipantDetailPage extends GetView<ParticipantResultController> {
return const Center(child: Text('Data peserta tidak tersedia.')); return const Center(child: Text('Data peserta tidak tersedia.'));
} }
return Column( return SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [ 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), _buildParticipantHeader(participant),
Expanded( Expanded(
child: ListView.builder( child: ListView.builder(
@ -47,8 +65,10 @@ class ParticipantDetailPage extends GetView<ParticipantResultController> {
), ),
), ),
], ],
),
); );
}), }),
),
); );
} }

View File

@ -11,7 +11,9 @@ class MonitorQuizView extends GetView<MonitorQuizController> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return PopScope(
canPop: false,
child: Scaffold(
backgroundColor: AppColors.background, backgroundColor: AppColors.background,
body: SafeArea( body: SafeArea(
child: Padding( child: Padding(
@ -50,6 +52,7 @@ class MonitorQuizView extends GetView<MonitorQuizController> {
), ),
), ),
), ),
),
); );
} }

View File

@ -1,6 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.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/component/global_button.dart';
import 'package:quiz_app/data/controllers/user_controller.dart'; import 'package:quiz_app/data/controllers/user_controller.dart';
import 'package:quiz_app/data/services/socket_service.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 @override
void onClose() { void onClose() {
fillInAnswerController.dispose(); fillInAnswerController.dispose();
_cancelTimer(); // Important: cancel timer when controller is closed _cancelTimer();
super.onClose(); super.onClose();
} }
} }
@ -140,7 +150,7 @@ class PlayQuizMultiplayerController extends GetxController {
class MultiplayerQuestionModel { class MultiplayerQuestionModel {
final int questionIndex; final int questionIndex;
final String question; final String question;
final String type; // 'option', 'true_false', 'fill_in_the_blank' final String type;
final int duration; final int duration;
final List<String>? options; final List<String>? options;

View File

@ -7,7 +7,9 @@ import 'package:quiz_app/feature/play_quiz_multiplayer/controller/play_quiz_cont
class PlayQuizMultiplayerView extends GetView<PlayQuizMultiplayerController> { class PlayQuizMultiplayerView extends GetView<PlayQuizMultiplayerController> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return PopScope(
canPop: false,
child: Scaffold(
backgroundColor: const Color(0xFFF9FAFB), backgroundColor: const Color(0xFFF9FAFB),
body: Obx(() { body: Obx(() {
if (controller.isDone.value) { if (controller.isDone.value) {
@ -20,6 +22,7 @@ class PlayQuizMultiplayerView extends GetView<PlayQuizMultiplayerController> {
return _buildQuestionView(); return _buildQuestionView();
}), }),
),
); );
} }
@ -245,10 +248,7 @@ class PlayQuizMultiplayerView extends GetView<PlayQuizMultiplayerController> {
), ),
const SizedBox(height: 40), const SizedBox(height: 40),
ElevatedButton( ElevatedButton(
onPressed: () { onPressed: controller.goToDetailResult,
// Arahkan ke halaman hasil atau leaderboard
Get.back();
},
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF2563EB), backgroundColor: const Color(0xFF2563EB),
foregroundColor: Colors.white, foregroundColor: Colors.white,