// ignore_for_file: deprecated_member_use, duplicate_ignore import 'package:flutter/material.dart'; import '../../core/service_locator.dart'; import '../home/home_screen.dart'; import '../recipes/recipes_screen.dart'; import '../favourites/favourites_screen.dart'; import '../bookmarks/bookmarks_screen.dart'; import '../community/community_screen.dart'; import '../session/session_screen.dart'; import 'app_router.dart'; /// Main navigation scaffold with bottom navigation bar and centered Add button. class MainNavigationScaffold extends StatefulWidget { const MainNavigationScaffold({super.key}); @override State createState() => MainNavigationScaffoldState(); } class MainNavigationScaffoldState extends State { int _currentIndex = 0; bool _wasLoggedIn = false; bool get _isLoggedIn => ServiceLocator.instance.sessionService?.isLoggedIn ?? false; @override void initState() { super.initState(); _wasLoggedIn = _isLoggedIn; } @override void didChangeDependencies() { super.didChangeDependencies(); // Check if login state changed and rebuild if needed _checkLoginState(); } void _checkLoginState() { final isLoggedIn = _isLoggedIn; if (isLoggedIn != _wasLoggedIn) { _wasLoggedIn = isLoggedIn; // Rebuild after a short delay to ensure state is fully updated Future.delayed(const Duration(milliseconds: 100), () { if (mounted) { setState(() { // Trigger rebuild to update navigation bar }); } }); } } void _onSessionChanged() { // Called when login/logout happens - rebuild immediately if (mounted) { setState(() { _wasLoggedIn = _isLoggedIn; }); // Also check after a short delay to catch any async state changes Future.delayed(const Duration(milliseconds: 200), () { if (mounted) { setState(() { _wasLoggedIn = _isLoggedIn; }); } }); } } void _onItemTapped(int index) { final isLoggedIn = _isLoggedIn; // Only allow navigation to Recipes (1) and Bookmarks (2) if logged in // Community (4) and User (3) are always accessible if (!isLoggedIn && (index == 1 || index == 2)) { // Redirect to User/Session tab to prompt login setState(() { _currentIndex = 3; // User/Session tab }); return; } setState(() { _currentIndex = index; }); } /// Public method to navigate to User screen from AppBar. void navigateToUser() { setState(() { _currentIndex = 3; // User/Session tab }); } /// Public method to navigate to Favourites screen (used from Recipes AppBar). void navigateToFavourites() { final isLoggedIn = _isLoggedIn; if (!isLoggedIn) { // Redirect to User/Session tab to prompt login navigateToUser(); return; } // Navigate to Favourites as a full-screen route Navigator.push( context, MaterialPageRoute( builder: (context) => const FavouritesScreen(), ), ); } void _onAddRecipePressed(BuildContext context) async { final isLoggedIn = _isLoggedIn; // Only allow adding recipes if logged in if (!isLoggedIn) { // Redirect to User/Session tab to prompt login setState(() { _currentIndex = 3; // User/Session tab }); ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Please log in to add recipes'), duration: Duration(seconds: 1), ), ); return; } // Navigate to Add Recipe screen and reload recipes when returning final result = await Navigator.pushNamed(context, AppRoutes.addRecipe); // If recipe was saved, result will be true // Switch to Recipes tab to show the new recipe if (result == true) { setState(() { _currentIndex = 1; // Switch to Recipes tab }); } } Widget _buildScreen(int index) { switch (index) { case 0: return const HomeScreen(); case 1: // Recipes - only show if logged in, otherwise show login prompt // Use a key based on login state to force rebuild when login changes return RecipesScreen( key: _isLoggedIn ? const ValueKey('recipes_logged_in') : const ValueKey('recipes_logged_out'), ); case 2: // Bookmarks - only show if logged in // Use a key based on login state to force rebuild when login changes return BookmarksScreen(key: ValueKey(_isLoggedIn)); case 3: return SessionScreen(onSessionChanged: _onSessionChanged); case 4: // Community - always accessible return const CommunityScreen(); default: return const SizedBox(); } } @override Widget build(BuildContext context) { // Rebuild when login state changes by checking it in build final isLoggedIn = _isLoggedIn; // Check login state in build to trigger rebuilds _checkLoginState(); // Ensure current index is valid (if logged out, don't allow Recipes/Bookmarks) // Community (4) and User (3) are always accessible if (!isLoggedIn && (_currentIndex == 1 || _currentIndex == 2)) { WidgetsBinding.instance.addPostFrameCallback((_) { if (mounted) { setState(() { _currentIndex = 0; // Switch to Home if trying to access protected tabs }); } }); } return Scaffold( body: IndexedStack( index: _currentIndex, children: List.generate(5, (index) => _buildScreen(index)), ), bottomNavigationBar: _buildCustomBottomNav(context), ); } Widget _buildCustomBottomNav(BuildContext context) { final isLoggedIn = _isLoggedIn; return Container( decoration: BoxDecoration( color: Theme.of(context).bottomNavigationBarTheme.backgroundColor ?? Theme.of(context).scaffoldBackgroundColor, boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.1), blurRadius: 4, offset: const Offset(0, -2), ), ], ), child: SafeArea( child: Container( height: kBottomNavigationBarHeight, padding: const EdgeInsets.symmetric(horizontal: 8), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ // Left side items Expanded( child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ // Home _buildNavItem( icon: Icons.home, label: 'Home', index: 0, onTap: () => _onItemTapped(0), ), // Recipes - only show if logged in if (isLoggedIn) _buildNavItem( icon: Icons.menu_book, label: 'Recipes', index: 1, onTap: () => _onItemTapped(1), ), ], ), ), // Center Add Recipe button - only show if logged in if (isLoggedIn) Container( width: 56, height: 56, margin: const EdgeInsets.only(bottom: 8), child: Material( color: Theme.of(context).primaryColor, shape: const CircleBorder(), child: InkWell( onTap: () => _onAddRecipePressed(context), customBorder: const CircleBorder(), child: const Icon( Icons.add, color: Colors.white, size: 28, ), ), ), ), // Right side items Expanded( child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ // Bookmarks - only show if logged in if (isLoggedIn) _buildNavItem( icon: Icons.bookmark, label: 'Bookmarks', index: 2, onTap: () => _onItemTapped(2), ), // Community - always accessible _buildNavItem( icon: Icons.people, label: 'Community', index: 4, onTap: () => _onItemTapped(4), ), ], ), ), ], ), ), ), ); } Widget _buildNavItem({ required IconData icon, required String label, required int index, required VoidCallback onTap, }) { final isSelected = _currentIndex == index; return Expanded( child: Material( color: Colors.transparent, child: InkWell( onTap: onTap, child: Column( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( icon, color: isSelected ? (Theme.of(context).brightness == Brightness.dark ? Colors.blue.shade300 // Lighter blue for dark mode : Theme.of(context).primaryColor) : Theme.of(context).iconTheme.color?.withOpacity(0.6), size: 24, ), const SizedBox(height: 4), Text( label, style: TextStyle( fontSize: 12, color: isSelected ? (Theme.of(context).brightness == Brightness.dark ? Colors.blue.shade300 // Lighter blue for dark mode : Theme.of(context).primaryColor) // ignore: deprecated_member_use : Theme.of(context) .textTheme .bodySmall ?.color ?.withOpacity(0.6), fontWeight: isSelected ? FontWeight.w600 : FontWeight.normal, ), ), ], ), ), ), ); } }