import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../auth/auth_provider.dart'; import '../../features/auth/presentation/login_screen.dart'; import '../../features/auth/presentation/register_screen.dart'; import '../../features/auth/presentation/splash_screen.dart'; import '../../features/home/presentation/home_screen.dart'; import '../../features/establishments/presentation/establishment_detail_screen.dart'; import '../../features/wallet/presentation/wallet_screen.dart'; import '../../features/wallet/presentation/wallet_top_up_screen.dart'; import '../../features/booking/presentation/booking_modify_screen.dart'; import '../../features/booking/presentation/bookings_screen.dart'; import '../../features/machines/presentation/machine_action_screen.dart'; import '../../features/machines/presentation/machine_booking_screen.dart'; import '../../features/wash/presentation/qr_scanner_screen.dart'; import '../../features/wash/presentation/wash_screen.dart'; import '../../features/profile/presentation/profile_screen.dart'; import '../widgets/main_shell.dart'; /// Routes nommées de l'application. abstract final class AppRoutes { static const splash = '/splash'; static const login = '/login'; static const register = '/register'; static const home = '/'; static const wallet = '/wallet'; static const walletTopUp = '/wallet/top-up'; static const bookings = '/bookings'; static const washes = '/washes'; static const washScan = '/washes/scan'; static const profile = '/profile'; static const establishment = '/establishments/:uuid'; static String machineAction(String uuid) => '/machines/$uuid/action'; static String machineBooking(String uuid) => '/machines/$uuid/book'; static String bookingModify(String uuid) => '/bookings/$uuid/edit'; } /// Configuration GoRouter avec redirection selon l'état d'authentification. final appRouterProvider = Provider((ref) { final authState = ref.watch(authProvider); return GoRouter( initialLocation: AppRoutes.splash, refreshListenable: GoRouterRefreshStream(ref), redirect: (context, state) { final location = state.matchedLocation; final onSplash = location == AppRoutes.splash; final isAuthRoute = location == AppRoutes.login || location == AppRoutes.register; // Restauration de session en cours → écran de chargement. if (authState.isLoading) { return onSplash ? null : AppRoutes.splash; } // Session restaurée → quitter le splash. if (onSplash) { return authState.isAuthenticated ? AppRoutes.home : AppRoutes.login; } final isAuthenticated = authState.isAuthenticated; if (!isAuthenticated && !isAuthRoute) { return AppRoutes.login; } if (isAuthenticated && isAuthRoute) { return AppRoutes.home; } return null; }, routes: [ GoRoute( path: AppRoutes.splash, builder: (context, state) => const SplashScreen(), ), GoRoute( path: AppRoutes.login, builder: (context, state) => const LoginScreen(), ), GoRoute( path: AppRoutes.register, builder: (context, state) => const RegisterScreen(), ), ShellRoute( builder: (context, state, child) => MainShell(child: child), routes: [ GoRoute( path: AppRoutes.home, builder: (context, state) => const HomeScreen(), ), GoRoute( path: AppRoutes.bookings, builder: (context, state) => const BookingsScreen(), ), GoRoute( path: AppRoutes.washes, builder: (context, state) => const WashScreen(), ), GoRoute( path: AppRoutes.wallet, builder: (context, state) => const WalletScreen(), ), GoRoute( path: AppRoutes.profile, builder: (context, state) => const ProfileScreen(), ), ], ), GoRoute( path: AppRoutes.establishment, builder: (context, state) { final uuid = state.pathParameters['uuid']!; return EstablishmentDetailScreen(establishmentUuid: uuid); }, ), GoRoute( path: AppRoutes.washScan, builder: (context, state) => const QrScannerScreen(), ), GoRoute( path: AppRoutes.walletTopUp, builder: (context, state) => const WalletTopUpScreen(), ), GoRoute( path: '/machines/:uuid/action', builder: (context, state) { final uuid = state.pathParameters['uuid']!; return MachineActionScreen(machineUuid: uuid); }, ), GoRoute( path: '/machines/:uuid/book', builder: (context, state) { final uuid = state.pathParameters['uuid']!; return MachineBookingScreen(machineUuid: uuid); }, ), GoRoute( path: '/bookings/:uuid/edit', builder: (context, state) { final uuid = state.pathParameters['uuid']!; return BookingModifyScreen(bookingUuid: uuid); }, ), ], ); }); /// Écoute les changements Riverpod pour rafraîchir les redirections GoRouter. class GoRouterRefreshStream extends ChangeNotifier { GoRouterRefreshStream(this._ref) { _ref.listen(authProvider, (_, __) => notifyListeners()); } final Ref _ref; }