Files
mobile/lib/core/router/app_router.dart
T

160 lines
5.4 KiB
Dart

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<GoRouter>((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<AuthState>(authProvider, (_, __) => notifyListeners());
}
final Ref _ref;
}