import 'package:flutter/material.dart'; import '../../core/service_locator.dart'; import '../../data/session/session_service.dart'; import '../../data/local/local_storage_service.dart'; import '../../data/nostr/nostr_service.dart'; import '../../data/sync/sync_engine.dart'; import '../../data/firebase/firebase_service.dart'; import '../home/home_screen.dart'; import '../recipes/recipes_screen.dart'; import '../add_recipe/add_recipe_screen.dart'; import '../favourites/favourites_screen.dart'; import '../relay_management/relay_management_screen.dart'; import '../relay_management/relay_management_controller.dart'; import '../session/session_screen.dart'; /// Route names for the app navigation. class AppRoutes { static const String home = '/'; static const String recipes = '/recipes'; static const String addRecipe = '/add-recipe'; static const String favourites = '/favourites'; static const String relayManagement = '/relay-management'; static const String session = '/session'; static const String login = '/login'; } /// Route guard that requires authentication. class AuthGuard { final SessionService? sessionService; AuthGuard(this.sessionService); /// Checks if user is authenticated. bool get isAuthenticated => sessionService?.isLoggedIn ?? false; /// Redirects to login if not authenticated. String? checkAuth(String route) { if (_requiresAuth(route) && !isAuthenticated) { return AppRoutes.login; } return null; } /// Checks if a route requires authentication. bool _requiresAuth(String route) { // Routes that require authentication const protectedRoutes = [ AppRoutes.session, ]; return protectedRoutes.contains(route); } } /// App router for managing navigation and route guards. class AppRouter { final SessionService? sessionService; final LocalStorageService? localStorageService; final NostrService? nostrService; final SyncEngine? syncEngine; final FirebaseService? firebaseService; late final AuthGuard _authGuard; AppRouter({ this.sessionService, this.localStorageService, this.nostrService, this.syncEngine, this.firebaseService, }) { _authGuard = AuthGuard(sessionService); } /// Generates routes for the app. Route? generateRoute(RouteSettings settings) { // Check route guard final redirect = _authGuard.checkAuth(settings.name ?? ''); if (redirect != null) { return MaterialPageRoute( builder: (_) => _buildLoginScreen(), settings: settings, ); } switch (settings.name) { case AppRoutes.home: return MaterialPageRoute( builder: (_) => const HomeScreen(), settings: settings, ); case AppRoutes.recipes: return MaterialPageRoute( builder: (_) => const RecipesScreen(), settings: settings, ); case AppRoutes.addRecipe: return MaterialPageRoute( builder: (_) => const AddRecipeScreen(), settings: settings, ); case AppRoutes.favourites: return MaterialPageRoute( builder: (_) => const FavouritesScreen(), settings: settings, ); case AppRoutes.relayManagement: final nostrService = ServiceLocator.instance.nostrService; final syncEngine = ServiceLocator.instance.syncEngine; if (nostrService == null || syncEngine == null) { return MaterialPageRoute( builder: (_) => _buildErrorScreen('Nostr service not available'), settings: settings, ); } return MaterialPageRoute( builder: (_) => RelayManagementScreen( controller: RelayManagementController( nostrService: nostrService, syncEngine: syncEngine, ), ), settings: settings, ); case AppRoutes.session: return MaterialPageRoute( builder: (_) => const SessionScreen(), settings: settings, ); case AppRoutes.login: return MaterialPageRoute( builder: (_) => _buildLoginScreen(), settings: settings, ); default: return MaterialPageRoute( builder: (_) => _buildErrorScreen('Route not found: ${settings.name}'), settings: settings, ); } } Widget _buildLoginScreen() { return Scaffold( appBar: AppBar( title: const Text('Login Required'), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const Icon( Icons.lock_outline, size: 64, color: Colors.grey, ), const SizedBox(height: 16), const Text( 'Please login to access this feature', style: TextStyle(fontSize: 16), ), const SizedBox(height: 24), ElevatedButton( onPressed: () { // Navigation will be handled by the navigation scaffold }, child: const Text('Go to Login'), ), ], ), ), ); } Widget _buildErrorScreen(String message) { return Scaffold( appBar: AppBar( title: const Text('Error'), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const Icon( Icons.error_outline, size: 64, color: Colors.red, ), const SizedBox(height: 16), Text( message, style: const TextStyle(fontSize: 16), textAlign: TextAlign.center, ), ], ), ), ); } }