develop #1

Merged
akhdanre merged 104 commits from develop into main 2025-07-10 12:38:53 +07:00
4 changed files with 135 additions and 2 deletions
Showing only changes of commit baee8e35db - Show all commits

View File

@ -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()],
)

View File

@ -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>(() => SearchQuizController());
}
}

View File

@ -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();
}
}

View File

@ -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<SearchQuizController> {
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()),
);
}
}