import 'package:bus_running_record/pages/home/page.dart' as home_v2; import 'package:bus_running_record/pages/home_page.dart' as legacy_home; import "package:bus_running_record/pages/operations_upload/page.dart"; import "package:bus_running_record/pages/invite/page.dart"; import "package:bus_running_record/pages/org_settings/page.dart"; import "package:bus_running_record/pages/auth/page.dart"; import "package:bus_running_record/pages/auth/verify_email_page.dart"; import "package:bus_running_record/pages/station_selection_page.dart"; import "package:bus_running_record/pages/trip_list_page.dart"; import "package:bus_running_record/provider/collaboration_state.dart"; import "package:bus_running_record/provider/supabase_state.dart"; import "package:bus_running_record/constants.dart"; import 'package:flutter/foundation.dart'; import 'package:go_router/go_router.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:provider/provider.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:supabase_flutter/supabase_flutter.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); await Hive.initFlutter(); await Supabase.initialize( url: kSupabaseEndpoint, anonKey: kSupabasePublishableKey, ); final supabaseProvider = SupabaseProvider(); runApp(RoadboundApp(supabaseProvider: supabaseProvider)); } class RoadboundApp extends StatefulWidget { const RoadboundApp({required this.supabaseProvider, super.key}); final SupabaseProvider supabaseProvider; @override State createState() => _RoadboundAppState(); } class _RoadboundAppState extends State { late final GoRouter _routerConfig = GoRouter( refreshListenable: widget.supabaseProvider, routes: [ LoginPage.route, VerifyEmailPage.route, home_v2.HomePage.rootRoute, home_v2.HomePage.channelRoute, legacy_home.HomePage.route, StationSelectionPage.route, TripListPage.route, OperationsUploadPage.route, InvitePage.route, OrganizationSettingsPage.route, ], redirect: (context, state) { final isLoggedIn = widget.supabaseProvider.isAuthenticated; final isValidatingSession = widget.supabaseProvider.isValidatingSession; final hasSession = widget.supabaseProvider.session != null; final requestedPath = state.uri.path; final onLogin = requestedPath == LoginPage.routePath; final onVerify = requestedPath == VerifyEmailPage.routePath; final onInvite = requestedPath.startsWith("/invite/"); final onLegacyFlow = requestedPath == legacy_home.HomePage.routePath || requestedPath == StationSelectionPage.routePath || requestedPath == TripListPage.routePath; if (onVerify) return null; if (onInvite) return null; if (onLegacyFlow) return null; // Avoid login flash on cold start: keep current route until // persisted session validation completes. if (hasSession && isValidatingSession) return null; if (!isLoggedIn && !onLogin) return LoginPage.routePath; if (isLoggedIn && onLogin) { final next = state.uri.queryParameters["next"]; return (next != null && next.isNotEmpty) ? next : "/"; } return null; }, ); @override Widget build(BuildContext context) { AdaptiveScaling? adaptiveScaling; if (defaultTargetPlatform == TargetPlatform.iOS) { adaptiveScaling = AdaptiveScaling(1.15); } return MultiProvider( providers: [ ChangeNotifierProvider.value(value: widget.supabaseProvider), ChangeNotifierProvider( create: (context) => CollaborationProvider(context.read()) ..initialize(), ), ], child: ShadcnApp.router( routerConfig: _routerConfig, scaling: adaptiveScaling, theme: ThemeData( colorScheme: ColorSchemes.darkNeutral, ), ), ); } }