diff --git a/lib/config/my_router.dart b/lib/config/my_router.dart index 9a58cbc2..ff86d055 100644 --- a/lib/config/my_router.dart +++ b/lib/config/my_router.dart @@ -293,6 +293,7 @@ // } import 'package:flutter/material.dart'; +import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:go_router/go_router.dart'; import 'package:uae_stat/presentation/Screens/Bottom%20Navigation%20Pages/UAE_Numbers/Social/marriages.dart'; import 'package:uae_stat/presentation/Screens/auth_verification/registration.dart'; @@ -326,25 +327,36 @@ import '../presentation/routes/drawer_routes/Drawer Items/user_guide/user_guide. import '../presentation/routes/drawer_routes/Drawer Items/manage_users.dart'; final pbService = PocketBaseService(); +final FlutterSecureStorage _secureStorage = const FlutterSecureStorage(); -Future getInitialRoute() async { - bool isLoggedIn = await pbService.loadSession(); - return isLoggedIn ? '/myhomepage' : '/login'; +Future _checkSession() async { + print('_checkSession'); + await Future.delayed(Duration(seconds: 2)); // Optional splash effect + + String? sessionToken = + await _secureStorage.read(key: "FlutterSecureStorage.session"); + print('sessionToken $sessionToken'); + + if (sessionToken != null && sessionToken.isNotEmpty) { + print('_checkSession home'); + return "/myhomepage"; // Redirect to home page if session is valid + } else { + print('_checkSession login'); + return "/login"; // Redirect to login page if session is invalid + } } final GoRouter router = GoRouter( routes: [ - GoRoute( - path: '/', - //builder: (context, state) => LoginRoute(), - builder: (context, state) => LoginRoute(), - ), // GoRoute( // path: '/', - // redirect: (context, state) async { - // return await getInitialRoute(); - // }, + // //builder: (context, state) => LoginRoute(), + // builder: (context, state) => LoginRoute(), // ), + GoRoute( + path: '/', + redirect: (context, state) async => await _checkSession(), + ), GoRoute( path: '/internetcheck', builder: (context, state) => InternetCheck(), diff --git a/lib/presentation/routes/auth_routes/login_route.dart b/lib/presentation/routes/auth_routes/login_route.dart index e4f1ee20..c2d17004 100644 --- a/lib/presentation/routes/auth_routes/login_route.dart +++ b/lib/presentation/routes/auth_routes/login_route.dart @@ -1,7 +1,10 @@ +import 'dart:convert'; + import 'package:external_repos/external_repos.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -28,6 +31,7 @@ import '../../components/my_toggle.dart'; class LoginRoute extends HookConsumerWidget { final pb = PocketBase('https://pb.venbait.in'); + final FlutterSecureStorage _secureStorage = const FlutterSecureStorage(); final _pbService = PocketBaseService(); // final _pb = PocketBase('http://127.0.0.1:8090'); // final bool isLoginScreen; // Pass `true` if this is the login screen @@ -35,6 +39,7 @@ class LoginRoute extends HookConsumerWidget { LoginRoute({super.key}); dynamic userData; String? role; + int? loginCount; static final formKey = GlobalKey(); @@ -83,11 +88,41 @@ class LoginRoute extends HookConsumerWidget { } } - Future saveUserId(String userId) async { + Future saveUserId(String userId, count) async { + print(count); final prefs = await SharedPreferences.getInstance(); await prefs.setString('userId', userId); // Save userId locally + await prefs.setString('login_count', count.toString()); } + // Future authenticateAndStoreData() async { + // try { + // // Perform authentication + // final authData = await pb + // .collection("users") + // .authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com'); + // + // // Check if authentication is successful + // if (pb.authStore.isValid) { + // print("Authentication successful!"); + // print("Token: ${pb.authStore.token}"); + // // print("User ID: ${pb.authStore.record.id}"); + // + // // Store the token and user ID in local storage + // await _secureStorage.write( + // key: "FlutterSecureStorage.session", value: pb.authStore.token); + // // await _secureStorage.write( + // // key: "FlutterSecureStorage.userId", value: pb.authStore.record.id); + // + // print("Session and User ID stored in local storage."); + // } else { + // print("Authentication failed."); + // } + // } catch (e) { + // print("Error during authentication: $e"); + // } + // } + @override Widget build(BuildContext context, WidgetRef ref) { final locale = ref.watch(localeProvider); @@ -305,6 +340,10 @@ class LoginRoute extends HookConsumerWidget { if (response.statusCode == 200) { print("Login success API call successful: ${response.body}"); + final count = jsonDecode(response.body); + loginCount = + count["login_count"]; // Directly assign it as an int + print(loginCount); } else { print( "Failed to call login success API. Status code: ${response.statusCode}"); @@ -313,7 +352,7 @@ class LoginRoute extends HookConsumerWidget { print("Error calling login success API: $e"); } - await saveUserId(userId); + await saveUserId(userId, loginCount); } try { final bool isProfileComplete = await profileStatus(userId); diff --git a/lib/presentation/routes/bottom_bar_routes/tab_routes/home_route.dart b/lib/presentation/routes/bottom_bar_routes/tab_routes/home_route.dart index e4d22b45..6d7b850e 100644 --- a/lib/presentation/routes/bottom_bar_routes/tab_routes/home_route.dart +++ b/lib/presentation/routes/bottom_bar_routes/tab_routes/home_route.dart @@ -233,6 +233,7 @@ class EconomyStatsState extends ConsumerState { print('render finished'); _showHomeTour(); } else { + print('render delayed'); Future.delayed(Duration(milliseconds: 100), _starTourRender); } } @@ -804,7 +805,19 @@ class EconomyStatsState extends ConsumerState { super.initState(); final locale = ref.read(localeProvider); fetchData(locale?.languageCode ?? 'en'); - _fetchUserData(); + // _fetchUserData(); + _loadLoginCount(); + } + + Future _loadLoginCount() async { + final prefs = await SharedPreferences.getInstance(); + String? loginCount = prefs.getString('login_count'); + print('Login Count: $loginCount'); // Debugging + if (loginCount == '1') { + WidgetsBinding.instance.addPostFrameCallback((_) { + _starTourRender(); + }); + } } // @override @@ -820,33 +833,35 @@ class EconomyStatsState extends ConsumerState { return prefs.getString('userId'); // Retrieve the userId } - Future _fetchUserData() async { - try { - final userId = await getUserId(); - print('EDIT PROFILE isPageLoad'); - final adminAuth = await _pb.admins - .authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com'); - final adminToken = adminAuth.token; - print('adminToken- $adminToken'); - final userDetailsResponse = await _pb.collection('users').getOne( - userId!, - headers: { - 'Authorization': 'Bearer $adminToken', - }, - ); - final loginCount = userDetailsResponse.data['login_count']; - print(loginCount); - if (loginCount == 1) { - setState(() { - WidgetsBinding.instance.addPostFrameCallback((_) { - _starTourRender(); - }); - }); - } - } catch (e) { - print('Error fetching user details: $e'); - } - } + // Future _fetchUserData() async { + // try { + // final userId = await getUserId(); + // print('EDIT PROFILE isPageLoad'); + // final adminAuth = await _pb.admins + // .authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com'); + // final adminToken = adminAuth.token; + // print('adminToken- $adminToken'); + // final userDetailsResponse = await _pb.collection('users').getOne( + // userId!, + // headers: { + // 'Authorization': 'Bearer $adminToken', + // }, + // ); + // final loginCount = userDetailsResponse.data['login_count']; + // print(loginCount); + // if (loginCount == 1) { + // print('_starTourRender count 1'); + // setState(() { + // print('_starTourRender'); + // WidgetsBinding.instance.addPostFrameCallback((_) { + // _starTourRender(); + // }); + // }); + // } + // } catch (e) { + // print('Error fetching user details: $e'); + // } + // } Future fetchData(locale) async { const baseUrl = 'https://pb.venbait.in/api/getHomePageData'; diff --git a/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart b/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart index 5067f8da..b4c99a17 100644 --- a/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart +++ b/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart @@ -4,12 +4,15 @@ import 'dart:convert'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:go_router/go_router.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:pocketbase/pocketbase.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:tutorial_coach_mark/tutorial_coach_mark.dart'; +import 'package:uae_stat/config/injector.dart'; +import 'package:uae_stat/domain/repos/t_auth_repo.dart'; import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/bottom_bar_asset_icon_path.dart'; import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/drawer_asset_icon_path.dart'; @@ -63,6 +66,8 @@ class _BaseScaffoldState extends ConsumerState { final GlobalKey drawerKey = GlobalKey(); late double toggleHeight = 0; bool isLoggedOut = false; + final FlutterSecureStorage _secureStorage = const FlutterSecureStorage(); + static final _repo = getIt.call(); @override void initState() { @@ -145,7 +150,7 @@ class _BaseScaffoldState extends ConsumerState { Align( alignment: Alignment.bottomRight, child: Padding( - padding: const EdgeInsets.only(right:10.0), + padding: const EdgeInsets.only(right: 10.0), child: Text( '5/7', style: const TextStyle( @@ -195,9 +200,10 @@ class _BaseScaffoldState extends ConsumerState { .state = true; ref .read(previousChartsTourProvider - .notifier) + .notifier) .state = false; - context.go('/chartScreen/hotels?bgColor=0xFF90B0D5&mainTopic=ECONOMY&title=Hotel+Establishments'); + context.go( + '/chartScreen/hotels?bgColor=0xFF90B0D5&mainTopic=ECONOMY&title=Hotel+Establishments'); }, ), ), @@ -258,8 +264,8 @@ class _BaseScaffoldState extends ConsumerState { children: [ Align( alignment: Alignment.bottomRight, - child:Padding( - padding: const EdgeInsets.only(right:10.0), + child: Padding( + padding: const EdgeInsets.only(right: 10.0), child: Text( '6/7', style: const TextStyle( @@ -335,8 +341,7 @@ class _BaseScaffoldState extends ConsumerState { ), ), TargetContent( - padding: EdgeInsets.only( - right: screenWidth * 0.7, top: 30), + padding: EdgeInsets.only(right: screenWidth * 0.7, top: 30), align: ContentAlign.right, child: Container( width: 200, @@ -393,8 +398,8 @@ class _BaseScaffoldState extends ConsumerState { children: [ Align( alignment: Alignment.bottomRight, - child:Padding( - padding: const EdgeInsets.only(right:10.0), + child: Padding( + padding: const EdgeInsets.only(right: 10.0), child: Text( '7/7', style: const TextStyle( @@ -451,10 +456,10 @@ class _BaseScaffoldState extends ConsumerState { .state = true; ref .read( - previousChartsTourProvider.notifier) + previousChartsTourProvider.notifier) .state = true; ref.read(homeTourProvider.notifier).state = - true; + true; ref .read(previousHomeTourProvider.notifier) .state = true; @@ -463,7 +468,7 @@ class _BaseScaffoldState extends ConsumerState { .state = true; ref .read(previousScaffoldTourProvider - .notifier) + .notifier) .state = true; tutorialCoachMark.finish(); }, @@ -496,7 +501,7 @@ class _BaseScaffoldState extends ConsumerState { ), TargetContent( padding: - EdgeInsets.only(left: screenWidth * 0.7, top: toggleHeight), + EdgeInsets.only(left: screenWidth * 0.7, top: toggleHeight), align: ContentAlign.left, child: Container( width: 200, @@ -593,8 +598,13 @@ class _BaseScaffoldState extends ConsumerState { // setState(() { // isLoggedOut = true; // }); + // prefs.clear(); + await _repo.logout(); + // state = const AsyncData(null); + // _pb.authStore.clear(); + // await _secureStorage.delete(key: "FlutterSecureStorage.session"); prefs.clear(); - context.go('/'); + context.go('/login'); } @override @@ -737,7 +747,7 @@ class _BaseScaffoldState extends ConsumerState { ListTile( leading: Image.asset( DrawerAssetIconPath.feedback, - color: Colors.black , + color: Colors.black, width: 20, height: 20, ), @@ -747,13 +757,13 @@ class _BaseScaffoldState extends ConsumerState { ), if (role == 'admin') ListTile( -leading: Image.asset( + leading: Image.asset( DrawerAssetIconPath.manageUser, - color: Colors.black , + color: Colors.black, width: 20, height: 20, ), - // title: Text('Manage User'), + // title: Text('Manage User'), title: Text( AppLocalizations.of(context)!.manage_user, ), @@ -767,7 +777,7 @@ leading: Image.asset( ListTile( leading: Image.asset( DrawerAssetIconPath.guide, - color: Colors.black , + color: Colors.black, width: 20, height: 20, ), @@ -833,52 +843,68 @@ leading: Image.asset( type: BottomNavigationBarType.fixed, items: [ BottomNavigationBarItem( - icon: Padding( - padding: const EdgeInsets.only(bottom: 4), // Adjust this for spacing - child: Image.asset( - BottomBarAssetIconPath.home, - color: _getSelectedIndex(currentRoute) == 0 ? Colors.black : Color(0xFF989898), - width: 20, - height: 20, - ),), + icon: Padding( + padding: + const EdgeInsets.only(bottom: 4), // Adjust this for spacing + child: Image.asset( + BottomBarAssetIconPath.home, + color: _getSelectedIndex(currentRoute) == 0 + ? Colors.black + : Color(0xFF989898), + width: 20, + height: 20, + ), + ), // label: 'Home', label: AppLocalizations.of(context)!.nav_home, ), BottomNavigationBarItem( // icon: Icon(Icons.map), - icon:Padding( - padding: const EdgeInsets.only(bottom: 4), // Adjust this for spacing - child: Image.asset( - BottomBarAssetIconPath.uaeMap, - color: _getSelectedIndex(currentRoute) == 1 ? Colors.black : Color(0xFF989898), - width: 20, - height: 20, - ),), + icon: Padding( + padding: + const EdgeInsets.only(bottom: 4), // Adjust this for spacing + child: Image.asset( + BottomBarAssetIconPath.uaeMap, + color: _getSelectedIndex(currentRoute) == 1 + ? Colors.black + : Color(0xFF989898), + width: 20, + height: 20, + ), + ), // label: 'UAE Numbers' label: AppLocalizations.of(context)!.nav_uae, ), BottomNavigationBarItem( -icon: Padding( - padding: const EdgeInsets.only(bottom: 4), // Adjust this for spacing - child: Image.asset( - BottomBarAssetIconPath.ranking, - color: _getSelectedIndex(currentRoute) == 2 ? Colors.black : Color(0xFF989898), - width: 20, - height: 20, - ),), - // label: 'Competitiveness', + icon: Padding( + padding: + const EdgeInsets.only(bottom: 4), // Adjust this for spacing + child: Image.asset( + BottomBarAssetIconPath.ranking, + color: _getSelectedIndex(currentRoute) == 2 + ? Colors.black + : Color(0xFF989898), + width: 20, + height: 20, + ), + ), + // label: 'Competitiveness', label: AppLocalizations.of(context)!.nav_competitiveness, ), BottomNavigationBarItem( - icon: Padding( - padding: const EdgeInsets.only(bottom: 4), // Adjust this for spacing - child: Image.asset( - BottomBarAssetIconPath.globe, - color: _getSelectedIndex(currentRoute) == 2 ? Colors.black : Color(0xFF989898), - width: 20, - height: 20, - ),), - // label: 'Country Profile', + icon: Padding( + padding: + const EdgeInsets.only(bottom: 4), // Adjust this for spacing + child: Image.asset( + BottomBarAssetIconPath.globe, + color: _getSelectedIndex(currentRoute) == 2 + ? Colors.black + : Color(0xFF989898), + width: 20, + height: 20, + ), + ), + // label: 'Country Profile', label: AppLocalizations.of(context)!.country_profile, ), ],