33import 'package:flutter/material.dart' ;
44import 'package:go_router/go_router.dart' ;
55import 'package:flutter_riverpod/flutter_riverpod.dart' ;
6+ import 'package:shared_preferences/shared_preferences.dart' ;
67
78import '../../features/auth/screens/login_screen.dart' ;
89import '../../features/dashboard/screens/dashboard_screen.dart' ;
@@ -16,6 +17,9 @@ import '../../features/report/screens/report_screen.dart';
1617import '../../features/settings/screens/settings_screen.dart' ;
1718import '../../features/profile/screens/profile_screen.dart' ;
1819import '../../features/about/screens/about_screen.dart' ;
20+ import '../features/onboarding/screens/onboarding_screen.dart' ;
21+ import '../features/settings/screens/privacy_policy_screen.dart' ;
22+ import '../features/settings/screens/terms_screen.dart' ;
1923
2024class AppRoutes {
2125 static const login = '/login' ;
@@ -30,18 +34,53 @@ class AppRoutes {
3034 static const settings = '/settings' ;
3135 static const profile = '/profile' ;
3236 static const about = '/about' ;
37+ static const onboarding = '/onboarding' ;
38+ static const privacy = '/settings/privacy' ;
39+ static const terms = '/settings/terms' ;
3340}
3441
42+ final onboardingProvider = FutureProvider <bool >((ref) async {
43+ final prefs = await SharedPreferences .getInstance ();
44+ return prefs.getBool ('onboarding_complete' ) ?? false ;
45+ });
46+
3547final appRouterProvider = Provider <GoRouter >((ref) {
48+ final onboardingComplete = ref.watch (onboardingProvider);
49+
3650 return GoRouter (
37- initialLocation: AppRoutes .login,
51+ initialLocation: AppRoutes .dashboard,
52+ redirect: (context, state) {
53+ if (onboardingComplete.isLoading) return null ;
54+
55+ final completed = onboardingComplete.value ?? false ;
56+ final isGoingToOnboarding = state.matchedLocation == AppRoutes .onboarding;
57+
58+ if (! completed && ! isGoingToOnboarding) {
59+ return AppRoutes .onboarding;
60+ }
61+
62+ // If completed and trying to go back to onboarding, redirect to home
63+ if (completed && isGoingToOnboarding) {
64+ return AppRoutes .dashboard;
65+ }
66+
67+ if (state.uri.toString () == '/' || state.uri.toString () == '' ) {
68+ return AppRoutes .dashboard;
69+ }
70+ return null ;
71+ },
3872 debugLogDiagnostics: true ,
3973 routes: [
4074 GoRoute (
4175 path: AppRoutes .login,
4276 name: 'login' ,
4377 builder: (context, state) => const LoginScreen (),
4478 ),
79+ GoRoute (
80+ path: AppRoutes .onboarding,
81+ name: 'onboarding' ,
82+ builder: (context, state) => const OnboardingScreen (),
83+ ),
4584 ShellRoute (
4685 builder: (context, state, child) => AppShell (child: child),
4786 routes: [
@@ -105,8 +144,17 @@ final appRouterProvider = Provider<GoRouter>((ref) {
105144 name: 'settings' ,
106145 builder: (context, state) => const SettingsScreen (),
107146 ),
147+ GoRoute (
148+ path: AppRoutes .privacy,
149+ builder: (context, state) => const PrivacyPolicyScreen (),
150+ ),
151+ GoRoute (
152+ path: AppRoutes .terms,
153+ builder: (context, state) => const TermsScreen (),
154+ ),
108155 GoRoute (
109156 path: AppRoutes .profile,
157+
110158 name: 'profile' ,
111159 builder: (context, state) => const ProfileScreen (),
112160 ),
@@ -211,32 +259,37 @@ class _NavItem extends StatelessWidget {
211259 @override
212260 Widget build (BuildContext context) {
213261 final isActive = current.startsWith (route);
214- return Tooltip (
215- message: label,
216- preferBelow: false ,
217- child: InkWell (
218- onTap: () => context.go (route),
219- borderRadius: BorderRadius .circular (12 ),
220- child: Container (
221- width: 48 ,
222- height: 48 ,
223- margin: const EdgeInsets .symmetric (vertical: 4 ),
224- decoration: BoxDecoration (
225- gradient: isActive
226- ? const LinearGradient (
227- colors: [Color (0xFF6366F1 ), Color (0xFF8B5CF6 )],
228- begin: Alignment .topLeft,
229- end: Alignment .bottomRight,
230- )
231- : null ,
232- borderRadius: BorderRadius .circular (12 ),
233- ),
234- child: Icon (
235- icon,
236- size: 22 ,
237- color: isActive
238- ? Colors .white
239- : const Color (0xFF908FA0 ),
262+ return Semantics (
263+ label: 'Navigation to $label ' ,
264+ button: true ,
265+ enabled: true ,
266+ child: Tooltip (
267+ message: label,
268+ preferBelow: false ,
269+ child: InkWell (
270+ onTap: () => context.go (route),
271+ borderRadius: BorderRadius .circular (12 ),
272+ child: Container (
273+ width: 48 ,
274+ height: 48 ,
275+ margin: const EdgeInsets .symmetric (vertical: 4 ),
276+ decoration: BoxDecoration (
277+ gradient: isActive
278+ ? const LinearGradient (
279+ colors: [Color (0xFF6366F1 ), Color (0xFF8B5CF6 )],
280+ begin: Alignment .topLeft,
281+ end: Alignment .bottomRight,
282+ )
283+ : null ,
284+ borderRadius: BorderRadius .circular (12 ),
285+ ),
286+ child: Icon (
287+ icon,
288+ size: 22 ,
289+ color: isActive
290+ ? Colors .white
291+ : const Color (0xFF908FA0 ),
292+ ),
240293 ),
241294 ),
242295 ),
0 commit comments