import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:supabase_flutter/supabase_flutter.dart'; import '../../features/authentication/presentation/pages/login_page.dart'; import '../../features/authentication/presentation/pages/signup_page.dart'; import '../../features/home/presentation/pages/home_page.dart'; import '../../features/authentication/presentation/pages/splash_page.dart'; import '../../features/authentication/presentation/pages/reset_password_page.dart'; import '../../features/authentication/presentation/pages/reset_password_confirm_page.dart'; import '../../features/authentication/presentation/pages/update_password_page.dart'; /// Application router configuration /// /// Handles navigation with authentication state awareness and protected routes class AppRouter { static final GoRouter _router = GoRouter( initialLocation: '/', debugLogDiagnostics: true, redirect: (context, state) { // Use Supabase directly for auth state checking final currentUser = Supabase.instance.client.auth.currentUser; // Allow splash page regardless of auth state if (state.uri.toString() == '/splash') { return null; } // If not authenticated and trying to access protected route, redirect to login // Allow password reset routes regardless of auth state for deep linking if (currentUser == null && !state.uri.toString().startsWith('/login') && !state.uri.toString().startsWith('/signup') && !state.uri.toString().startsWith('/reset-password') && !state.uri.toString().startsWith('/update-password')) { return '/login'; } // If authenticated and on auth pages (except password reset), redirect to home if (currentUser != null && (state.uri.toString().startsWith('/login') || state.uri.toString().startsWith('/signup') || state.uri.toString().startsWith('/reset-password'))) { return '/home'; } return null; }, routes: [ // Splash route - initial loading screen GoRoute( path: '/splash', builder: (context, state) => const SplashPage(), ), // Authentication routes (public) GoRoute( path: '/login', builder: (context, state) => const LoginPage(), ), GoRoute( path: '/signup', builder: (context, state) => const SignupPage(), ), // Password reset routes (public for deep linking) GoRoute( path: '/reset-password', builder: (context, state) => const ResetPasswordPage(), ), GoRoute( path: '/reset-password-confirm', builder: (context, state) { // Extract token from query parameters for deep linking final token = state.uri.queryParameters['token']; final email = state.uri.queryParameters['email']; // Store token data for password reset flow if (token != null && email != null) { // TODO: Store token and email securely for password reset flow // This could be done through a provider or secure storage print('Password reset token received for email: $email'); } return const ResetPasswordConfirmPage(); }, ), GoRoute( path: '/update-password', builder: (context, state) { // Extract token from query parameters if present final token = state.uri.queryParameters['token']; final email = state.uri.queryParameters['email']; // Store token data for password update if (token != null && email != null) { // TODO: Store token and email securely for password update flow print('Password update token received for email: $email'); } return const UpdatePasswordPage(); }, ), // Protected routes (require authentication) GoRoute( path: '/home', builder: (context, state) => const HomePage(), ), // Root route - redirects based on auth state GoRoute( path: '/', redirect: (context, state) { final currentUser = Supabase.instance.client.auth.currentUser; return currentUser != null ? '/home' : '/splash'; }, ), ], errorBuilder: (context, state) => 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( 'Page not found', style: Theme.of(context).textTheme.headlineSmall, ), const SizedBox(height: 8), Text( 'Could not find: ${state.uri.toString()}', style: Theme.of(context).textTheme.bodyMedium?.copyWith( color: Colors.grey[600], ), ), const SizedBox(height: 24), ElevatedButton( onPressed: () { // Navigate to home or login based on auth state final currentUser = Supabase.instance.client.auth.currentUser; if (currentUser != null) { GoRouter.of(context).go('/home'); } else { GoRouter.of(context).go('/login'); } }, child: const Text('Go Home'), ), const SizedBox(height: 16), // Special handling for malformed password reset URLs if (state.uri.toString().contains('reset')) ...[ TextButton( onPressed: () => GoRouter.of(context).go('/reset-password'), child: const Text('Request New Reset Link'), ), ], ], ), ), ), ); /// Get the router instance static GoRouter get router => _router; }