fix: limitation on the quiz creation
This commit is contained in:
parent
1a465fd0d1
commit
80e6704bec
|
@ -13,4 +13,6 @@ class APIEndpoint {
|
||||||
|
|
||||||
static const String historyQuiz = "/history";
|
static const String historyQuiz = "/history";
|
||||||
static const String detailHistoryQuiz = "/history/detail";
|
static const String detailHistoryQuiz = "/history/detail";
|
||||||
|
|
||||||
|
static const String subject = "/subject";
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
class CustomNotification {
|
||||||
|
static void _showSnackbar({
|
||||||
|
required String title,
|
||||||
|
required String message,
|
||||||
|
required IconData icon,
|
||||||
|
required Color backgroundColor,
|
||||||
|
Color textColor = Colors.white,
|
||||||
|
Color iconColor = Colors.white,
|
||||||
|
}) {
|
||||||
|
Get.snackbar(
|
||||||
|
title,
|
||||||
|
message,
|
||||||
|
icon: Icon(icon, color: iconColor),
|
||||||
|
backgroundColor: backgroundColor,
|
||||||
|
colorText: textColor,
|
||||||
|
borderRadius: 12,
|
||||||
|
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
|
||||||
|
snackPosition: SnackPosition.TOP,
|
||||||
|
duration: const Duration(seconds: 3),
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 16),
|
||||||
|
isDismissible: true,
|
||||||
|
forwardAnimationCurve: Curves.easeOutBack,
|
||||||
|
reverseAnimationCurve: Curves.easeInBack,
|
||||||
|
boxShadows: [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.black26,
|
||||||
|
blurRadius: 10,
|
||||||
|
offset: Offset(0, 4),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void success({required String title, required String message}) {
|
||||||
|
_showSnackbar(
|
||||||
|
title: title,
|
||||||
|
message: message,
|
||||||
|
icon: Icons.check_circle_outline,
|
||||||
|
backgroundColor: Colors.green.shade600,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void error({required String title, required String message}) {
|
||||||
|
_showSnackbar(
|
||||||
|
title: title,
|
||||||
|
message: message,
|
||||||
|
icon: Icons.error_outline,
|
||||||
|
backgroundColor: Colors.red.shade600,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void warning({required String title, required String message}) {
|
||||||
|
_showSnackbar(
|
||||||
|
title: title,
|
||||||
|
message: message,
|
||||||
|
icon: Icons.warning_amber_rounded,
|
||||||
|
backgroundColor: Colors.orange.shade700,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,6 +8,7 @@ class QuizCreateRequestModel {
|
||||||
final int totalQuiz;
|
final int totalQuiz;
|
||||||
final int limitDuration;
|
final int limitDuration;
|
||||||
final String authorId;
|
final String authorId;
|
||||||
|
final String subjectId;
|
||||||
final List<QuestionListing> questionListings;
|
final List<QuestionListing> questionListings;
|
||||||
|
|
||||||
QuizCreateRequestModel({
|
QuizCreateRequestModel({
|
||||||
|
@ -18,6 +19,7 @@ class QuizCreateRequestModel {
|
||||||
required this.totalQuiz,
|
required this.totalQuiz,
|
||||||
required this.limitDuration,
|
required this.limitDuration,
|
||||||
required this.authorId,
|
required this.authorId,
|
||||||
|
required this.subjectId,
|
||||||
required this.questionListings,
|
required this.questionListings,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -30,6 +32,7 @@ class QuizCreateRequestModel {
|
||||||
'total_quiz': totalQuiz,
|
'total_quiz': totalQuiz,
|
||||||
'limit_duration': limitDuration,
|
'limit_duration': limitDuration,
|
||||||
'author_id': authorId,
|
'author_id': authorId,
|
||||||
|
"subject_id": subjectId,
|
||||||
'question_listings': questionListings.map((e) => e.toJson()).toList(),
|
'question_listings': questionListings.map((e) => e.toJson()).toList(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
class SubjectModel {
|
||||||
|
final String id;
|
||||||
|
final String name;
|
||||||
|
final String alias;
|
||||||
|
final String description;
|
||||||
|
|
||||||
|
SubjectModel({
|
||||||
|
required this.id,
|
||||||
|
required this.name,
|
||||||
|
required this.alias,
|
||||||
|
required this.description,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory SubjectModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
return SubjectModel(
|
||||||
|
id: json['id'],
|
||||||
|
name: json['name'],
|
||||||
|
alias: json['alias'],
|
||||||
|
description: json['description'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return {
|
||||||
|
'id': id,
|
||||||
|
'name': name,
|
||||||
|
'alias': alias,
|
||||||
|
'description': description,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:quiz_app/core/endpoint/api_endpoint.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/subject/subject_model.dart';
|
||||||
|
import 'package:quiz_app/data/providers/dio_client.dart';
|
||||||
|
|
||||||
|
class SubjectService extends GetxService {
|
||||||
|
late final Dio _dio;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onInit() {
|
||||||
|
_dio = Get.find<ApiClient>().dio;
|
||||||
|
super.onInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<BaseResponseModel<List<SubjectModel>>?> getSubject() async {
|
||||||
|
try {
|
||||||
|
final response = await _dio.get(
|
||||||
|
APIEndpoint.subject,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
final parsedResponse = BaseResponseModel<List<SubjectModel>>.fromJson(
|
||||||
|
response.data,
|
||||||
|
(data) => (data as List).map((e) => SubjectModel.fromJson(e as Map<String, dynamic>)).toList(),
|
||||||
|
);
|
||||||
|
|
||||||
|
return parsedResponse;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
logC.e("Quiz creation error: $e");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,12 +1,18 @@
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.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/quiz_service.dart';
|
import 'package:quiz_app/data/services/quiz_service.dart';
|
||||||
|
import 'package:quiz_app/data/services/subject_service.dart';
|
||||||
import 'package:quiz_app/feature/quiz_preview/controller/quiz_preview_controller.dart';
|
import 'package:quiz_app/feature/quiz_preview/controller/quiz_preview_controller.dart';
|
||||||
|
|
||||||
class QuizPreviewBinding extends Bindings {
|
class QuizPreviewBinding extends Bindings {
|
||||||
@override
|
@override
|
||||||
void dependencies() {
|
void dependencies() {
|
||||||
Get.lazyPut<QuizService>(() => QuizService());
|
Get.lazyPut<QuizService>(() => QuizService());
|
||||||
Get.lazyPut<QuizPreviewController>(() => QuizPreviewController(Get.find<QuizService>(), Get.find<UserController>()));
|
Get.lazyPut<SubjectService>(() => SubjectService());
|
||||||
|
Get.lazyPut<QuizPreviewController>(() => QuizPreviewController(
|
||||||
|
Get.find<QuizService>(),
|
||||||
|
Get.find<UserController>(),
|
||||||
|
Get.find<SubjectService>(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,16 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:quiz_app/app/const/enums/question_type.dart';
|
import 'package:quiz_app/app/const/enums/question_type.dart';
|
||||||
import 'package:quiz_app/app/routes/app_pages.dart';
|
import 'package:quiz_app/app/routes/app_pages.dart';
|
||||||
|
import 'package:quiz_app/core/utils/custom_notification.dart';
|
||||||
import 'package:quiz_app/core/utils/logger.dart';
|
import 'package:quiz_app/core/utils/logger.dart';
|
||||||
import 'package:quiz_app/data/controllers/user_controller.dart';
|
import 'package:quiz_app/data/controllers/user_controller.dart';
|
||||||
|
import 'package:quiz_app/data/models/base/base_model.dart';
|
||||||
import 'package:quiz_app/data/models/quiz/question_create_request.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/question_listings_model.dart';
|
||||||
import 'package:quiz_app/data/models/quiz/quiestion_data_model.dart';
|
import 'package:quiz_app/data/models/quiz/quiestion_data_model.dart';
|
||||||
|
import 'package:quiz_app/data/models/subject/subject_model.dart';
|
||||||
import 'package:quiz_app/data/services/quiz_service.dart';
|
import 'package:quiz_app/data/services/quiz_service.dart';
|
||||||
|
import 'package:quiz_app/data/services/subject_service.dart';
|
||||||
|
|
||||||
class QuizPreviewController extends GetxController {
|
class QuizPreviewController extends GetxController {
|
||||||
final TextEditingController titleController = TextEditingController();
|
final TextEditingController titleController = TextEditingController();
|
||||||
|
@ -15,17 +19,29 @@ class QuizPreviewController extends GetxController {
|
||||||
|
|
||||||
final QuizService _quizService;
|
final QuizService _quizService;
|
||||||
final UserController _userController;
|
final UserController _userController;
|
||||||
|
final SubjectService _subjectService;
|
||||||
|
|
||||||
QuizPreviewController(this._quizService, this._userController);
|
QuizPreviewController(
|
||||||
|
this._quizService,
|
||||||
|
this._userController,
|
||||||
|
this._subjectService,
|
||||||
|
);
|
||||||
|
|
||||||
RxBool isPublic = false.obs;
|
RxBool isPublic = false.obs;
|
||||||
|
|
||||||
late final List<QuestionData> data;
|
late final List<QuestionData> data;
|
||||||
|
|
||||||
|
RxList<SubjectModel> subjects = <SubjectModel>[].obs;
|
||||||
|
|
||||||
|
RxInt subjectIndex = 0.obs;
|
||||||
|
|
||||||
|
String subjectId = "";
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
super.onInit();
|
super.onInit();
|
||||||
loadData();
|
loadData();
|
||||||
|
loadSubjectData();
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadData() {
|
void loadData() {
|
||||||
|
@ -37,12 +53,31 @@ class QuizPreviewController extends GetxController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void loadSubjectData() async {
|
||||||
|
BaseResponseModel<List<SubjectModel>>? respnse = await _subjectService.getSubject();
|
||||||
|
if (respnse != null) {
|
||||||
|
subjects.assignAll(respnse.data!);
|
||||||
|
subjectId = subjects[0].id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> onSaveQuiz() async {
|
Future<void> onSaveQuiz() async {
|
||||||
final title = titleController.text.trim();
|
final title = titleController.text.trim();
|
||||||
final description = descriptionController.text.trim();
|
final description = descriptionController.text.trim();
|
||||||
|
|
||||||
if (title.isEmpty || description.isEmpty) {
|
if (title.isEmpty || description.isEmpty) {
|
||||||
Get.snackbar('Error', 'Judul dan deskripsi tidak boleh kosong!');
|
CustomNotification.error(
|
||||||
|
title: 'Error',
|
||||||
|
message: 'Judul dan deskripsi tidak boleh kosong!',
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.length < 10) {
|
||||||
|
CustomNotification.error(
|
||||||
|
title: 'Error',
|
||||||
|
message: 'Jumlah soal harus 10 atau lebih',
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,12 +93,17 @@ class QuizPreviewController extends GetxController {
|
||||||
totalQuiz: data.length,
|
totalQuiz: data.length,
|
||||||
limitDuration: data.length * 30,
|
limitDuration: data.length * 30,
|
||||||
authorId: _userController.userData!.id,
|
authorId: _userController.userData!.id,
|
||||||
|
subjectId: subjectId,
|
||||||
questionListings: _mapQuestionsToListings(data),
|
questionListings: _mapQuestionsToListings(data),
|
||||||
);
|
);
|
||||||
final success = await _quizService.createQuiz(quizRequest);
|
final success = await _quizService.createQuiz(quizRequest);
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
Get.snackbar('Sukses', 'Kuis berhasil disimpan!');
|
CustomNotification.success(
|
||||||
|
title: 'Sukses',
|
||||||
|
message: 'Kuis berhasil disimpan!',
|
||||||
|
);
|
||||||
|
|
||||||
Get.offAllNamed(AppRoutes.mainPage, arguments: 2);
|
Get.offAllNamed(AppRoutes.mainPage, arguments: 2);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -110,6 +150,11 @@ class QuizPreviewController extends GetxController {
|
||||||
}).toList();
|
}).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void onSubjectTap(String id, int index) {
|
||||||
|
subjectId = id;
|
||||||
|
subjectIndex.value = index;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onClose() {
|
void onClose() {
|
||||||
titleController.dispose();
|
titleController.dispose();
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:quiz_app/app/const/colors/app_colors.dart';
|
||||||
|
import 'package:quiz_app/data/models/subject/subject_model.dart';
|
||||||
|
|
||||||
|
class SubjectDropdownComponent extends StatelessWidget {
|
||||||
|
final List<SubjectModel> data;
|
||||||
|
final void Function(String id, int index) onItemTap;
|
||||||
|
final int selectedIndex;
|
||||||
|
|
||||||
|
const SubjectDropdownComponent({
|
||||||
|
super.key,
|
||||||
|
required this.data,
|
||||||
|
required this.onItemTap,
|
||||||
|
required this.selectedIndex,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return DropdownButtonFormField<String>(
|
||||||
|
value: selectedIndex >= 0 && selectedIndex < data.length ? data[selectedIndex].id : null,
|
||||||
|
items: data.asMap().entries.map((entry) {
|
||||||
|
// final index = entry.key;
|
||||||
|
final subject = entry.value;
|
||||||
|
return DropdownMenuItem<String>(
|
||||||
|
value: subject.id,
|
||||||
|
child: Text('${subject.alias} - ${subject.name}'),
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
onChanged: (value) {
|
||||||
|
if (value != null) {
|
||||||
|
final index = data.indexWhere((e) => e.id == value);
|
||||||
|
if (index != -1) {
|
||||||
|
onItemTap(value, index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
decoration: InputDecoration(
|
||||||
|
filled: true,
|
||||||
|
fillColor: Colors.white,
|
||||||
|
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
borderSide: const BorderSide(color: AppColors.borderLight),
|
||||||
|
),
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
borderSide: const BorderSide(color: AppColors.borderLight),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,7 @@ import 'package:quiz_app/component/global_text_field.dart';
|
||||||
import 'package:quiz_app/component/label_text_field.dart';
|
import 'package:quiz_app/component/label_text_field.dart';
|
||||||
import 'package:quiz_app/component/widget/question_container_widget.dart';
|
import 'package:quiz_app/component/widget/question_container_widget.dart';
|
||||||
import 'package:quiz_app/feature/quiz_preview/controller/quiz_preview_controller.dart';
|
import 'package:quiz_app/feature/quiz_preview/controller/quiz_preview_controller.dart';
|
||||||
|
import 'package:quiz_app/feature/quiz_preview/view/component/subject_dropdown_component.dart';
|
||||||
|
|
||||||
class QuizPreviewPage extends GetView<QuizPreviewController> {
|
class QuizPreviewPage extends GetView<QuizPreviewController> {
|
||||||
const QuizPreviewPage({super.key});
|
const QuizPreviewPage({super.key});
|
||||||
|
@ -14,9 +15,22 @@ class QuizPreviewPage extends GetView<QuizPreviewController> {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: AppColors.background,
|
backgroundColor: AppColors.background,
|
||||||
appBar: AppBar(
|
appBar: _buildAppBar(),
|
||||||
|
body: SafeArea(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(20.0),
|
||||||
|
child: _buildContent(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
PreferredSizeWidget _buildAppBar() {
|
||||||
|
return AppBar(
|
||||||
backgroundColor: AppColors.background,
|
backgroundColor: AppColors.background,
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
|
centerTitle: true,
|
||||||
|
iconTheme: const IconThemeData(color: AppColors.darkText),
|
||||||
title: const Text(
|
title: const Text(
|
||||||
'Preview Quiz',
|
'Preview Quiz',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
|
@ -24,23 +38,28 @@ class QuizPreviewPage extends GetView<QuizPreviewController> {
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
centerTitle: true,
|
);
|
||||||
iconTheme: const IconThemeData(color: AppColors.darkText),
|
}
|
||||||
),
|
|
||||||
body: SafeArea(
|
Widget _buildContent() {
|
||||||
child: Padding(
|
return SingleChildScrollView(
|
||||||
padding: const EdgeInsets.all(20.0),
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
LabelTextField(label: "Judul"),
|
const LabelTextField(label: "Judul"),
|
||||||
GlobalTextField(controller: controller.titleController),
|
GlobalTextField(controller: controller.titleController),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
LabelTextField(label: "Deskripsi Singkat"),
|
const LabelTextField(label: "Deskripsi Singkat"),
|
||||||
GlobalTextField(controller: controller.descriptionController),
|
GlobalTextField(controller: controller.descriptionController),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
_buildPublicCheckbox(), // Ganti ke sini
|
const LabelTextField(label: "Mata Pelajaran"),
|
||||||
|
Obx(() => SubjectDropdownComponent(
|
||||||
|
data: controller.subjects.toList(),
|
||||||
|
onItemTap: controller.onSubjectTap,
|
||||||
|
selectedIndex: controller.subjectIndex.value,
|
||||||
|
)),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
_buildPublicCheckbox(),
|
||||||
const SizedBox(height: 30),
|
const SizedBox(height: 30),
|
||||||
const Divider(thickness: 1.2, color: AppColors.borderLight),
|
const Divider(thickness: 1.2, color: AppColors.borderLight),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
|
@ -52,9 +71,6 @@ class QuizPreviewPage extends GetView<QuizPreviewController> {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,27 +84,16 @@ class QuizPreviewPage extends GetView<QuizPreviewController> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildPublicCheckbox() {
|
Widget _buildPublicCheckbox() {
|
||||||
return Obx(
|
return Obx(() => GestureDetector(
|
||||||
() => GestureDetector(
|
onTap: controller.isPublic.toggle,
|
||||||
onTap: () {
|
|
||||||
controller.isPublic.toggle();
|
|
||||||
},
|
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
children: [
|
children: [
|
||||||
Checkbox(
|
Checkbox(
|
||||||
value: controller.isPublic.value,
|
value: controller.isPublic.value,
|
||||||
activeColor: AppColors.primaryBlue, // Pakai warna biru utama
|
activeColor: AppColors.primaryBlue,
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4)),
|
||||||
borderRadius: BorderRadius.circular(4),
|
side: const BorderSide(color: AppColors.primaryBlue, width: 2),
|
||||||
),
|
onChanged: (val) => controller.isPublic.value = val ?? false,
|
||||||
side: const BorderSide(
|
|
||||||
color: AppColors.primaryBlue, // Pinggirannya juga biru
|
|
||||||
width: 2,
|
|
||||||
),
|
|
||||||
onChanged: (value) {
|
|
||||||
controller.isPublic.value = value ?? false;
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
const Text(
|
const Text(
|
||||||
|
@ -101,7 +106,6 @@ class QuizPreviewPage extends GetView<QuizPreviewController> {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue