feat: done working on the room maker
This commit is contained in:
parent
ca9e9cde7d
commit
481bfbe228
|
@ -25,6 +25,8 @@ import 'package:quiz_app/feature/quiz_result/binding/quiz_result_binding.dart';
|
|||
import 'package:quiz_app/feature/quiz_result/view/quiz_result_view.dart';
|
||||
import 'package:quiz_app/feature/register/binding/register_binding.dart';
|
||||
import 'package:quiz_app/feature/register/view/register_page.dart';
|
||||
import 'package:quiz_app/feature/room_maker/binding/room_maker_binding.dart';
|
||||
import 'package:quiz_app/feature/room_maker/view/room_maker_view.dart';
|
||||
import 'package:quiz_app/feature/search/binding/search_binding.dart';
|
||||
import 'package:quiz_app/feature/splash_screen/presentation/splash_screen_page.dart';
|
||||
|
||||
|
@ -99,6 +101,11 @@ class AppPages {
|
|||
name: AppRoutes.detailHistoryPage,
|
||||
page: () => DetailHistoryView(),
|
||||
binding: DetailHistoryBinding(),
|
||||
),
|
||||
GetPage(
|
||||
name: AppRoutes.roomPage,
|
||||
page: () => RoomMakerView(),
|
||||
binding: RoomMakerBinding(),
|
||||
)
|
||||
];
|
||||
}
|
||||
|
|
|
@ -17,4 +17,6 @@ abstract class AppRoutes {
|
|||
static const resultQuizPage = "/quiz/result";
|
||||
|
||||
static const detailHistoryPage = "/history/detail";
|
||||
|
||||
static const roomPage = "/room/quiz";
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
class GlobalTextField extends StatelessWidget {
|
||||
final TextEditingController controller;
|
||||
|
@ -8,22 +9,24 @@ class GlobalTextField extends StatelessWidget {
|
|||
final bool isPassword;
|
||||
final bool obscureText;
|
||||
final VoidCallback? onToggleVisibility;
|
||||
final TextInputType textInputType;
|
||||
|
||||
const GlobalTextField({
|
||||
super.key,
|
||||
required this.controller,
|
||||
this.hintText,
|
||||
this.labelText,
|
||||
this.limitTextLine = 1,
|
||||
this.isPassword = false,
|
||||
this.obscureText = false,
|
||||
this.onToggleVisibility,
|
||||
});
|
||||
const GlobalTextField(
|
||||
{super.key,
|
||||
required this.controller,
|
||||
this.hintText,
|
||||
this.labelText,
|
||||
this.limitTextLine = 1,
|
||||
this.isPassword = false,
|
||||
this.obscureText = false,
|
||||
this.onToggleVisibility,
|
||||
this.textInputType = TextInputType.text});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return TextField(
|
||||
controller: controller,
|
||||
keyboardType: textInputType,
|
||||
obscureText: isPassword ? obscureText : false,
|
||||
maxLines: limitTextLine, // <-- ini tambahan dari limitTextLine
|
||||
decoration: InputDecoration(
|
||||
|
|
|
@ -27,13 +27,6 @@ class HomeController extends GetxController {
|
|||
|
||||
RxList<SubjectModel> subjects = <SubjectModel>[].obs;
|
||||
|
||||
void goToQuizCreation() => Get.toNamed(AppRoutes.quizCreatePage);
|
||||
|
||||
void goToSearch() {
|
||||
final navController = Get.find<NavigationController>();
|
||||
navController.changePage(1);
|
||||
}
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
_getRecomendationQuiz();
|
||||
|
@ -55,6 +48,15 @@ class HomeController extends GetxController {
|
|||
}
|
||||
}
|
||||
|
||||
void goToQuizCreation() => Get.toNamed(AppRoutes.quizCreatePage);
|
||||
|
||||
void goToRoomMaker() => Get.toNamed(AppRoutes.roomPage);
|
||||
|
||||
void goToSearch() {
|
||||
final navController = Get.find<NavigationController>();
|
||||
navController.changePage(1);
|
||||
}
|
||||
|
||||
void onRecommendationTap(String quizId) => Get.toNamed(AppRoutes.detailQuizPage, arguments: quizId);
|
||||
|
||||
void goToListingsQuizPage(ListingType page, {String? subjectId, String? subjecName}) => Get.toNamed(
|
||||
|
|
|
@ -35,7 +35,7 @@ class HomeView extends GetView<HomeController> {
|
|||
// ButtonOption di luar Padding
|
||||
ButtonOption(
|
||||
onCreate: controller.goToQuizCreation,
|
||||
onCreateRoom: () {},
|
||||
onCreateRoom: controller.goToRoomMaker,
|
||||
onJoinRoom: () {},
|
||||
),
|
||||
Padding(
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
import 'package:get/get.dart';
|
||||
import 'package:quiz_app/feature/room_maker/controller/room_maker_controller.dart';
|
||||
|
||||
class RoomMakerBinding extends Bindings {
|
||||
@override
|
||||
void dependencies() {
|
||||
Get.lazyPut(() => RoomMakerController());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:quiz_app/data/models/quiz/quiz_listing_model.dart';
|
||||
|
||||
class RoomMakerController extends GetxController {
|
||||
final roomName = ''.obs;
|
||||
final selectedQuiz = Rxn<QuizListingModel>();
|
||||
|
||||
RxBool isOnwQuiz = true.obs;
|
||||
|
||||
final TextEditingController nameTC = TextEditingController();
|
||||
final TextEditingController maxPlayerTC = TextEditingController();
|
||||
|
||||
final availableQuizzes = <QuizListingModel>[
|
||||
QuizListingModel(
|
||||
quizId: '1',
|
||||
authorId: 'u1',
|
||||
authorName: 'Admin',
|
||||
title: 'Sejarah Indonesia',
|
||||
description: 'Kuis tentang kerajaan dan sejarah nusantara.',
|
||||
date: '2025-05-01',
|
||||
totalQuiz: 10,
|
||||
duration: 600,
|
||||
),
|
||||
QuizListingModel(
|
||||
quizId: '2',
|
||||
authorId: 'u2',
|
||||
authorName: 'Guru IPA',
|
||||
title: 'Ilmu Pengetahuan Alam',
|
||||
description: 'Kuis IPA untuk kelas 8.',
|
||||
date: '2025-04-28',
|
||||
totalQuiz: 15,
|
||||
duration: 900,
|
||||
),
|
||||
].obs;
|
||||
|
||||
void createRoom() {
|
||||
if (roomName.value.trim().isEmpty || selectedQuiz.value == null) {
|
||||
Get.snackbar("Gagal", "Nama room dan kuis harus dipilih.");
|
||||
return;
|
||||
}
|
||||
|
||||
final quiz = selectedQuiz.value!;
|
||||
print("Membuat room:");
|
||||
print("- Nama: ${roomName.value}");
|
||||
print("- Quiz: ${quiz.title}");
|
||||
print("- Durasi: ${quiz.duration} detik");
|
||||
print("- Jumlah Soal: ${quiz.totalQuiz}");
|
||||
}
|
||||
|
||||
void onQuizSourceChange(bool base) {
|
||||
isOnwQuiz.value = base;
|
||||
}
|
||||
|
||||
void onQuizChoosen(String quizId) {
|
||||
final selected = availableQuizzes.firstWhere((e) => e.quizId == quizId);
|
||||
selectedQuiz.value = selected;
|
||||
}
|
||||
|
||||
void onCreateRoom() {}
|
||||
}
|
|
@ -0,0 +1,175 @@
|
|||
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/text/text_style.dart';
|
||||
import 'package:quiz_app/component/global_button.dart';
|
||||
import 'package:quiz_app/component/global_text_field.dart';
|
||||
import 'package:quiz_app/component/label_text_field.dart';
|
||||
import 'package:quiz_app/component/quiz_container_component.dart';
|
||||
import 'package:quiz_app/feature/room_maker/controller/room_maker_controller.dart';
|
||||
|
||||
class RoomMakerView extends GetView<RoomMakerController> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: AppColors.background,
|
||||
appBar: AppBar(title: Text("Buat Room Quiz")),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
children: [
|
||||
LabelTextField(
|
||||
label: "Room Name",
|
||||
),
|
||||
GlobalTextField(
|
||||
controller: controller.nameTC,
|
||||
),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
LabelTextField(label: "Jumlah Maksimal Pemain"),
|
||||
GlobalTextField(
|
||||
controller: controller.maxPlayerTC,
|
||||
textInputType: TextInputType.number,
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
quizMeta(),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
_buildModeSelector(),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Expanded(
|
||||
child: Container(
|
||||
child: Obx(() => ListView.builder(
|
||||
itemCount: controller.availableQuizzes.length,
|
||||
itemBuilder: (context, index) {
|
||||
return QuizContainerComponent(
|
||||
data: controller.availableQuizzes[index],
|
||||
onTap: controller.onQuizChoosen,
|
||||
);
|
||||
})),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
GlobalButton(text: "Buat Room", onPressed: controller.onCreateRoom)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget quizMeta() {
|
||||
return Obx(() {
|
||||
final quiz = controller.selectedQuiz.value;
|
||||
if (quiz == null) return SizedBox.shrink();
|
||||
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.all(16),
|
||||
margin: const EdgeInsets.only(top: 16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.05),
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, 4),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Kuis yang Dipilih",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
_buildMetaRow("Judul", quiz.title),
|
||||
_buildMetaRow("Deskripsi", quiz.description),
|
||||
_buildMetaRow("Jumlah Soal", quiz.totalQuiz.toString()),
|
||||
_buildMetaRow("Durasi", "${quiz.duration ~/ 60} menit"),
|
||||
],
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Widget _buildMetaRow(String label, String value) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: 8.0),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text("$label: ", style: AppTextStyles.subtitle),
|
||||
Expanded(
|
||||
child: Text(
|
||||
value,
|
||||
style: AppTextStyles.subtitle,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildModeSelector() {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.background,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(color: AppColors.borderLight),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
_buildModeButton('kuismu', controller.isOnwQuiz, true),
|
||||
_buildModeButton('Rekomendasi', controller.isOnwQuiz, false),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildModeButton(String label, RxBool isSelected, bool base) {
|
||||
return Expanded(
|
||||
child: InkWell(
|
||||
onTap: () => controller.onQuizSourceChange(base),
|
||||
child: Obx(
|
||||
() => Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 14),
|
||||
decoration: BoxDecoration(
|
||||
color: isSelected.value == base ? AppColors.primaryBlue : Colors.transparent,
|
||||
borderRadius: base
|
||||
? BorderRadius.only(
|
||||
topLeft: Radius.circular(10),
|
||||
bottomLeft: Radius.circular(10),
|
||||
)
|
||||
: BorderRadius.only(
|
||||
topRight: Radius.circular(10),
|
||||
bottomRight: Radius.circular(10),
|
||||
),
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: Text(
|
||||
label,
|
||||
style: TextStyle(
|
||||
color: isSelected.value == base ? Colors.white : AppColors.softGrayText,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue