From e2d801b8a515afabf1d4e62c230e5d45c6dd1043 Mon Sep 17 00:00:00 2001 From: akhdanre Date: Sat, 26 Apr 2025 15:54:17 +0700 Subject: [PATCH] feat: navigation --- lib/app/routes/app_pages.dart | 11 ++++ lib/app/routes/app_routes.dart | 2 + lib/feature/history/view/history_view.dart | 10 ++++ .../login/controllers/login_controller.dart | 2 +- .../bindings/navigation_binding.dart | 10 ++++ .../controllers/navigation_controller.dart | 9 +++ lib/feature/navigation/views/navbar_view.dart | 56 +++++++++++++++++++ lib/feature/profile/view/profile_view.dart | 10 ++++ lib/feature/search/view/search_view.dart | 10 ++++ .../presentation/splash_screen_page.dart | 2 +- 10 files changed, 120 insertions(+), 2 deletions(-) create mode 100644 lib/feature/history/view/history_view.dart create mode 100644 lib/feature/navigation/bindings/navigation_binding.dart create mode 100644 lib/feature/navigation/controllers/navigation_controller.dart create mode 100644 lib/feature/navigation/views/navbar_view.dart create mode 100644 lib/feature/profile/view/profile_view.dart create mode 100644 lib/feature/search/view/search_view.dart diff --git a/lib/app/routes/app_pages.dart b/lib/app/routes/app_pages.dart index 7b56701..571f99b 100644 --- a/lib/app/routes/app_pages.dart +++ b/lib/app/routes/app_pages.dart @@ -4,6 +4,8 @@ import 'package:quiz_app/feature/home/binding/home_binding.dart'; import 'package:quiz_app/feature/home/view/home_page.dart'; import 'package:quiz_app/feature/login/bindings/login_binding.dart'; import 'package:quiz_app/feature/login/view/login_page.dart'; +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/splash_screen/presentation/splash_screen_page.dart'; @@ -32,5 +34,14 @@ class AppPages { binding: HomeBinding(), middlewares: [AuthMiddleware()], ), + GetPage( + name: AppRoutes.mainPage, + page: () => NavbarView(), + bindings: [ + NavbarBinding(), + HomeBinding(), + ], + middlewares: [AuthMiddleware()], + ) ]; } diff --git a/lib/app/routes/app_routes.dart b/lib/app/routes/app_routes.dart index bde6d89..00e7b0f 100644 --- a/lib/app/routes/app_routes.dart +++ b/lib/app/routes/app_routes.dart @@ -5,4 +5,6 @@ abstract class AppRoutes { static const loginPage = "/login"; static const registerPage = "/register"; static const homePage = '/home'; + + static const mainPage = '/main'; } diff --git a/lib/feature/history/view/history_view.dart b/lib/feature/history/view/history_view.dart new file mode 100644 index 0000000..e7ba104 --- /dev/null +++ b/lib/feature/history/view/history_view.dart @@ -0,0 +1,10 @@ +import 'package:flutter/material.dart'; + +class HistoryView extends StatelessWidget { + const HistoryView({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold(); + } +} diff --git a/lib/feature/login/controllers/login_controller.dart b/lib/feature/login/controllers/login_controller.dart index 8160f24..63eac8d 100644 --- a/lib/feature/login/controllers/login_controller.dart +++ b/lib/feature/login/controllers/login_controller.dart @@ -111,5 +111,5 @@ class LoginController extends GetxController { } } - void goToRegsPage() => Get.toNamed(AppRoutes.registerPage); + void goToRegsPage() => Get.toNamed(AppRoutes.mainPage); } diff --git a/lib/feature/navigation/bindings/navigation_binding.dart b/lib/feature/navigation/bindings/navigation_binding.dart new file mode 100644 index 0000000..a3d6e66 --- /dev/null +++ b/lib/feature/navigation/bindings/navigation_binding.dart @@ -0,0 +1,10 @@ +// feature/navbar/binding/navbar_binding.dart +import 'package:get/get.dart'; +import 'package:quiz_app/feature/navigation/controllers/navigation_controller.dart'; + +class NavbarBinding extends Bindings { + @override + void dependencies() { + Get.lazyPut(() => NavigationController()); + } +} diff --git a/lib/feature/navigation/controllers/navigation_controller.dart b/lib/feature/navigation/controllers/navigation_controller.dart new file mode 100644 index 0000000..96ade1c --- /dev/null +++ b/lib/feature/navigation/controllers/navigation_controller.dart @@ -0,0 +1,9 @@ +import 'package:get/get.dart'; + +class NavigationController extends GetxController { + RxInt selectedIndex = 0.obs; + + void changePage(int page) { + selectedIndex.value = page; + } +} diff --git a/lib/feature/navigation/views/navbar_view.dart b/lib/feature/navigation/views/navbar_view.dart new file mode 100644 index 0000000..b85ccc7 --- /dev/null +++ b/lib/feature/navigation/views/navbar_view.dart @@ -0,0 +1,56 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:quiz_app/feature/history/view/history_view.dart'; +import 'package:quiz_app/feature/home/view/home_page.dart'; +import 'package:quiz_app/feature/navigation/controllers/navigation_controller.dart'; +import 'package:quiz_app/feature/profile/view/profile_view.dart'; +import 'package:quiz_app/feature/search/view/search_view.dart'; + +class NavbarView extends GetView { + const NavbarView({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Obx(() { + switch (controller.selectedIndex.value) { + case 0: + return const HomeView(); + case 1: + return const SearchView(); + case 2: + return const HistoryView(); + case 3: + return const ProfileView(); + default: + return const HomeView(); + } + }), + bottomNavigationBar: Obx( + () => BottomNavigationBar( + type: BottomNavigationBarType.fixed, // <=== ini tambahan penting! + currentIndex: controller.selectedIndex.value, + onTap: controller.changePage, + items: const [ + BottomNavigationBarItem( + icon: Icon(Icons.home), + label: 'Home', + ), + BottomNavigationBarItem( + icon: Icon(Icons.search), + label: 'Search', + ), + BottomNavigationBarItem( + icon: Icon(Icons.history), + label: 'History', + ), + BottomNavigationBarItem( + icon: Icon(Icons.person), + label: 'Profile', + ), + ], + ), + ), + ); + } +} diff --git a/lib/feature/profile/view/profile_view.dart b/lib/feature/profile/view/profile_view.dart new file mode 100644 index 0000000..bc41fd2 --- /dev/null +++ b/lib/feature/profile/view/profile_view.dart @@ -0,0 +1,10 @@ +import 'package:flutter/material.dart'; + +class ProfileView extends StatelessWidget { + const ProfileView({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold(); + } +} diff --git a/lib/feature/search/view/search_view.dart b/lib/feature/search/view/search_view.dart new file mode 100644 index 0000000..ea198aa --- /dev/null +++ b/lib/feature/search/view/search_view.dart @@ -0,0 +1,10 @@ +import 'package:flutter/material.dart'; + +class SearchView extends StatelessWidget { + const SearchView({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold(); + } +} diff --git a/lib/feature/splash_screen/presentation/splash_screen_page.dart b/lib/feature/splash_screen/presentation/splash_screen_page.dart index 4081eaa..eec56b5 100644 --- a/lib/feature/splash_screen/presentation/splash_screen_page.dart +++ b/lib/feature/splash_screen/presentation/splash_screen_page.dart @@ -15,7 +15,7 @@ class SplashScreenView extends StatelessWidget { await Future.delayed(const Duration(seconds: 2)); if (isLoggedIn) { - Get.offNamed(AppRoutes.homePage); + Get.offNamed(AppRoutes.mainPage); } else { Get.offNamed(AppRoutes.loginPage); }