feat: finish implement subject on the home and search
This commit is contained in:
parent
80e6704bec
commit
cd38b79bef
|
@ -1,11 +1,18 @@
|
|||
import 'package:get/get.dart';
|
||||
import 'package:quiz_app/data/services/quiz_service.dart';
|
||||
import 'package:quiz_app/data/services/subject_service.dart';
|
||||
import 'package:quiz_app/feature/home/controller/home_controller.dart';
|
||||
|
||||
class HomeBinding extends Bindings {
|
||||
@override
|
||||
void dependencies() {
|
||||
Get.lazyPut<QuizService>(() => QuizService());
|
||||
Get.lazyPut<HomeController>(() => HomeController(Get.find<QuizService>()));
|
||||
Get.lazyPut<SubjectService>(() => SubjectService());
|
||||
Get.lazyPut<HomeController>(
|
||||
() => HomeController(
|
||||
Get.find<QuizService>(),
|
||||
Get.find<SubjectService>(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,23 +3,40 @@ import 'package:quiz_app/app/routes/app_pages.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/quiz_listing_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/subject_service.dart';
|
||||
import 'package:quiz_app/feature/navigation/controllers/navigation_controller.dart';
|
||||
|
||||
class HomeController extends GetxController {
|
||||
final UserController _userController = Get.find<UserController>();
|
||||
|
||||
final QuizService _quizService;
|
||||
HomeController(this._quizService);
|
||||
final SubjectService _subjectService;
|
||||
|
||||
HomeController(
|
||||
this._quizService,
|
||||
this._subjectService,
|
||||
);
|
||||
|
||||
Rx<String> get userName => _userController.userName;
|
||||
Rx<String?> get userImage => _userController.userImage;
|
||||
|
||||
RxList<QuizListingModel> data = <QuizListingModel>[].obs;
|
||||
|
||||
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();
|
||||
loadSubjectData();
|
||||
super.onInit();
|
||||
}
|
||||
|
||||
|
@ -30,6 +47,13 @@ class HomeController extends GetxController {
|
|||
}
|
||||
}
|
||||
|
||||
void loadSubjectData() async {
|
||||
BaseResponseModel<List<SubjectModel>>? respnse = await _subjectService.getSubject();
|
||||
if (respnse != null) {
|
||||
subjects.assignAll(respnse.data!);
|
||||
}
|
||||
}
|
||||
|
||||
void onRecommendationTap(String quizId) => Get.toNamed(AppRoutes.detailQuizPage, arguments: quizId);
|
||||
|
||||
void goToListingsQuizPage() => Get.toNamed(AppRoutes.listingQuizPage);
|
||||
|
|
|
@ -1,8 +1,16 @@
|
|||
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 SearchComponent extends StatelessWidget {
|
||||
const SearchComponent({super.key});
|
||||
final Function() onSearchTap;
|
||||
final List<SubjectModel> subject;
|
||||
|
||||
const SearchComponent({
|
||||
super.key,
|
||||
required this.onSearchTap,
|
||||
required this.subject,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -52,12 +60,18 @@ class SearchComponent extends StatelessWidget {
|
|||
}
|
||||
|
||||
Widget _buildCategoryRow() {
|
||||
return Row(
|
||||
children: [
|
||||
_buildCategoryComponent("History"),
|
||||
const SizedBox(width: 8),
|
||||
_buildCategoryComponent("Science"),
|
||||
],
|
||||
return SizedBox(
|
||||
height: 30, // Set height for horizontal ListView
|
||||
child: ListView.builder(
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: subject.length,
|
||||
itemBuilder: (context, index) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(right: index != subject.length - 1 ? 8.0 : 0),
|
||||
child: _buildCategoryComponent(subject[index].alias),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -80,7 +94,10 @@ class SearchComponent extends StatelessWidget {
|
|||
}
|
||||
|
||||
Widget _buildSearchInput() {
|
||||
return Container(
|
||||
return GestureDetector(
|
||||
onTap: () => onSearchTap(),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
|
@ -88,16 +105,22 @@ class SearchComponent extends StatelessWidget {
|
|||
BoxShadow(
|
||||
color: Colors.black.withValues(alpha: 0.05),
|
||||
blurRadius: 6,
|
||||
offset: Offset(0, 2),
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: const TextField(
|
||||
decoration: InputDecoration(
|
||||
hintText: "Search for quizzes...",
|
||||
hintStyle: TextStyle(color: Color(0xFF6B778C)),
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
child: Row(
|
||||
children: const [
|
||||
Icon(Icons.search, color: Color(0xFF6B778C)),
|
||||
SizedBox(width: 8),
|
||||
Text(
|
||||
"Search for quizzes...",
|
||||
style: TextStyle(
|
||||
color: Color(0xFF6B778C),
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -41,7 +41,10 @@ class HomeView extends GetView<HomeController> {
|
|||
padding: const EdgeInsets.all(20),
|
||||
child: Column(
|
||||
children: [
|
||||
SearchComponent(),
|
||||
Obx(() => SearchComponent(
|
||||
onSearchTap: controller.goToSearch,
|
||||
subject: controller.subjects.toList(),
|
||||
)),
|
||||
const SizedBox(height: 20),
|
||||
Obx(
|
||||
() => RecomendationComponent(
|
||||
|
|
|
@ -154,7 +154,6 @@ class QuizPlayController extends GetxController {
|
|||
|
||||
await Future.delayed(Duration(seconds: 2));
|
||||
|
||||
print(quizData);
|
||||
|
||||
Get.offAllNamed(
|
||||
AppRoutes.resultQuizPage,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:get/get.dart';
|
||||
import 'package:quiz_app/data/services/quiz_service.dart';
|
||||
import 'package:quiz_app/data/services/subject_service.dart';
|
||||
import 'package:quiz_app/feature/search/controller/search_controller.dart';
|
||||
|
||||
class SearchBinding extends Bindings {
|
||||
|
@ -8,6 +9,12 @@ class SearchBinding extends Bindings {
|
|||
if (!Get.isRegistered<QuizService>()) {
|
||||
Get.lazyPut<QuizService>(() => QuizService());
|
||||
}
|
||||
Get.lazyPut<SearchQuizController>(() => SearchQuizController(Get.find<QuizService>()));
|
||||
|
||||
if (!Get.isRegistered()) Get.lazyPut<SubjectService>(() => SubjectService());
|
||||
|
||||
Get.lazyPut<SearchQuizController>(() => SearchQuizController(
|
||||
Get.find<QuizService>(),
|
||||
Get.find<SubjectService>(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,12 +3,18 @@ import 'package:get/get.dart';
|
|||
import 'package:quiz_app/app/routes/app_pages.dart';
|
||||
import 'package:quiz_app/data/models/base/base_model.dart';
|
||||
import 'package:quiz_app/data/models/quiz/quiz_listing_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/subject_service.dart';
|
||||
|
||||
class SearchQuizController extends GetxController {
|
||||
final QuizService _quizService;
|
||||
final SubjectService _subjectService;
|
||||
|
||||
SearchQuizController(this._quizService);
|
||||
SearchQuizController(
|
||||
this._quizService,
|
||||
this._subjectService,
|
||||
);
|
||||
|
||||
final searchController = TextEditingController();
|
||||
final searchText = ''.obs;
|
||||
|
@ -16,9 +22,12 @@ class SearchQuizController extends GetxController {
|
|||
RxList<QuizListingModel> recommendationQData = <QuizListingModel>[].obs;
|
||||
RxList<QuizListingModel> searchQData = <QuizListingModel>[].obs;
|
||||
|
||||
RxList<SubjectModel> subjects = <SubjectModel>[].obs;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
getRecomendation();
|
||||
loadSubjectData();
|
||||
super.onInit();
|
||||
searchController.addListener(() {
|
||||
searchText.value = searchController.text;
|
||||
|
@ -49,6 +58,15 @@ class SearchQuizController extends GetxController {
|
|||
|
||||
void goToListingsQuizPage() => Get.toNamed(AppRoutes.listingQuizPage);
|
||||
|
||||
void loadSubjectData() async {
|
||||
BaseResponseModel<List<SubjectModel>>? respnse = await _subjectService.getSubject();
|
||||
if (respnse != null) {
|
||||
subjects.assignAll(respnse.data!);
|
||||
}
|
||||
}
|
||||
|
||||
void goToDetailQuizListing() {}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
searchController.dispose();
|
||||
|
|
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:get/get.dart';
|
||||
import 'package:quiz_app/component/quiz_container_component.dart';
|
||||
import 'package:quiz_app/component/widget/recomendation_component.dart';
|
||||
import 'package:quiz_app/data/models/subject/subject_model.dart';
|
||||
import 'package:quiz_app/feature/search/controller/search_controller.dart';
|
||||
|
||||
class SearchView extends GetView<SearchQuizController> {
|
||||
|
@ -21,7 +22,7 @@ class SearchView extends GetView<SearchQuizController> {
|
|||
_buildSearchBar(),
|
||||
const SizedBox(height: 20),
|
||||
if (isSearching) ...[
|
||||
_buildCategoryFilter(),
|
||||
Obx(() => _buildCategoryFilter(controller.subjects.toList())),
|
||||
const SizedBox(height: 20),
|
||||
...controller.searchQData.map(
|
||||
(e) => QuizContainerComponent(data: e, onTap: controller.goToDetailPage),
|
||||
|
@ -78,17 +79,29 @@ class SearchView extends GetView<SearchQuizController> {
|
|||
);
|
||||
}
|
||||
|
||||
Widget _buildCategoryFilter() {
|
||||
final categories = ['Fisika', 'Matematika', 'Agama', 'English', 'Sejarah', 'Biologi'];
|
||||
Widget _buildCategoryFilter(List<SubjectModel> data) {
|
||||
return Wrap(
|
||||
spacing: 8,
|
||||
runSpacing: 8,
|
||||
children: categories.map((cat) {
|
||||
return Chip(
|
||||
label: Text(cat),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||
backgroundColor: Colors.white,
|
||||
side: const BorderSide(color: Colors.black12),
|
||||
spacing: 6,
|
||||
runSpacing: 1,
|
||||
children: data.map((cat) {
|
||||
return InkWell(
|
||||
onTap: () => controller.goToDetailQuizListing,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
|
||||
margin: const EdgeInsets.symmetric(vertical: 2),
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFFD6E4FF),
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
),
|
||||
child: Text(
|
||||
cat.alias,
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF0052CC),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue