From baee8e35dbfdd7d603a0e96db579fd20894dc37c Mon Sep 17 00:00:00 2001 From: akhdanre Date: Sat, 26 Apr 2025 16:06:03 +0700 Subject: [PATCH] feat: done slicing search --- lib/app/routes/app_pages.dart | 2 + .../search/binding/search_binding.dart | 9 ++ .../search/controller/search_controller.dart | 21 ++++ lib/feature/search/view/search_view.dart | 105 +++++++++++++++++- 4 files changed, 135 insertions(+), 2 deletions(-) create mode 100644 lib/feature/search/binding/search_binding.dart create mode 100644 lib/feature/search/controller/search_controller.dart diff --git a/lib/app/routes/app_pages.dart b/lib/app/routes/app_pages.dart index 571f99b..ceac4d1 100644 --- a/lib/app/routes/app_pages.dart +++ b/lib/app/routes/app_pages.dart @@ -8,6 +8,7 @@ import 'package:quiz_app/feature/navigation/bindings/navigation_binding.dart'; import 'package:quiz_app/feature/navigation/views/navbar_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/search/binding/search_binding.dart'; import 'package:quiz_app/feature/splash_screen/presentation/splash_screen_page.dart'; part 'app_routes.dart'; @@ -40,6 +41,7 @@ class AppPages { bindings: [ NavbarBinding(), HomeBinding(), + SearchBinding(), ], middlewares: [AuthMiddleware()], ) diff --git a/lib/feature/search/binding/search_binding.dart b/lib/feature/search/binding/search_binding.dart new file mode 100644 index 0000000..8ea4ccf --- /dev/null +++ b/lib/feature/search/binding/search_binding.dart @@ -0,0 +1,9 @@ +import 'package:get/get.dart'; +import 'package:quiz_app/feature/search/controller/search_controller.dart'; + +class SearchBinding extends Bindings { + @override + void dependencies() { + Get.lazyPut(() => SearchQuizController()); + } +} diff --git a/lib/feature/search/controller/search_controller.dart b/lib/feature/search/controller/search_controller.dart new file mode 100644 index 0000000..f8c5808 --- /dev/null +++ b/lib/feature/search/controller/search_controller.dart @@ -0,0 +1,21 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +class SearchQuizController extends GetxController { + final searchController = TextEditingController(); + final searchText = ''.obs; + + @override + void onInit() { + super.onInit(); + searchController.addListener(() { + searchText.value = searchController.text; + }); + } + + @override + void onClose() { + searchController.dispose(); + super.onClose(); + } +} diff --git a/lib/feature/search/view/search_view.dart b/lib/feature/search/view/search_view.dart index ea198aa..b985385 100644 --- a/lib/feature/search/view/search_view.dart +++ b/lib/feature/search/view/search_view.dart @@ -1,10 +1,111 @@ import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:quiz_app/component/quiz_container_component.dart'; +import 'package:quiz_app/feature/search/controller/search_controller.dart'; -class SearchView extends StatelessWidget { +class SearchView extends GetView { const SearchView({super.key}); @override Widget build(BuildContext context) { - return Scaffold(); + return Scaffold( + backgroundColor: const Color(0xFFF8F9FB), + body: SafeArea( + child: Padding( + padding: const EdgeInsets.all(16), + child: Obx(() { + final isSearching = controller.searchText.isNotEmpty; + + return ListView( + children: [ + _buildSearchBar(), + const SizedBox(height: 20), + if (isSearching) ...[ + _buildCategoryFilter(), + const SizedBox(height: 20), + const Text( + "Result", + style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16), + ), + const SizedBox(height: 10), + _buildQuizList(count: 5), + ] else ...[ + _buildSectionTitle("Rekomendasi Quiz"), + const SizedBox(height: 10), + _buildQuizList(), + const SizedBox(height: 30), + _buildSectionTitle("Quiz Populer"), + const SizedBox(height: 10), + _buildQuizList(), + ], + ], + ); + }), + ), + ), + ); + } + + Widget _buildSearchBar() { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 16), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(16), + boxShadow: const [ + BoxShadow( + color: Colors.black12, + blurRadius: 6, + offset: Offset(0, 2), + ), + ], + ), + child: TextField( + controller: controller.searchController, + decoration: const InputDecoration( + hintText: 'Cari quiz...', + border: InputBorder.none, + icon: Icon(Icons.search), + ), + ), + ); + } + + Widget _buildCategoryFilter() { + final categories = ['Fisika', 'Matematika', 'Agama', 'English', 'Sejarah', 'Biologi']; + 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), + ); + }).toList(), + ); + } + + Widget _buildSectionTitle(String title) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + title, + style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + ), + Text( + "Lihat semua", + style: TextStyle(fontSize: 14, color: Colors.blue.shade700), + ), + ], + ); + } + + Widget _buildQuizList({int count = 3}) { + return Column( + children: List.generate(count, (_) => const QuizContainerComponent()), + ); } }