session added and first time app tour added

This commit is contained in:
venbaittech 2025-02-06 19:15:27 +05:30
parent 5b922b4355
commit 428315b5c1
4 changed files with 186 additions and 94 deletions

View File

@ -293,6 +293,7 @@
// } // }
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:go_router/go_router.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/Bottom%20Navigation%20Pages/UAE_Numbers/Social/marriages.dart';
import 'package:uae_stat/presentation/Screens/auth_verification/registration.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'; import '../presentation/routes/drawer_routes/Drawer Items/manage_users.dart';
final pbService = PocketBaseService(); final pbService = PocketBaseService();
final FlutterSecureStorage _secureStorage = const FlutterSecureStorage();
Future<String> getInitialRoute() async { Future<String?> _checkSession() async {
bool isLoggedIn = await pbService.loadSession(); print('_checkSession');
return isLoggedIn ? '/myhomepage' : '/login'; 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( final GoRouter router = GoRouter(
routes: [ routes: [
GoRoute(
path: '/',
//builder: (context, state) => LoginRoute(),
builder: (context, state) => LoginRoute(),
),
// GoRoute( // GoRoute(
// path: '/', // path: '/',
// redirect: (context, state) async { // //builder: (context, state) => LoginRoute(),
// return await getInitialRoute(); // builder: (context, state) => LoginRoute(),
// },
// ), // ),
GoRoute(
path: '/',
redirect: (context, state) async => await _checkSession(),
),
GoRoute( GoRoute(
path: '/internetcheck', path: '/internetcheck',
builder: (context, state) => InternetCheck(), builder: (context, state) => InternetCheck(),

View File

@ -1,7 +1,10 @@
import 'dart:convert';
import 'package:external_repos/external_repos.dart'; import 'package:external_repos/external_repos.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_hooks/flutter_hooks.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:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
@ -28,6 +31,7 @@ import '../../components/my_toggle.dart';
class LoginRoute extends HookConsumerWidget { class LoginRoute extends HookConsumerWidget {
final pb = PocketBase('https://pb.venbait.in'); final pb = PocketBase('https://pb.venbait.in');
final FlutterSecureStorage _secureStorage = const FlutterSecureStorage();
final _pbService = PocketBaseService(); final _pbService = PocketBaseService();
// final _pb = PocketBase('http://127.0.0.1:8090'); // final _pb = PocketBase('http://127.0.0.1:8090');
// final bool isLoginScreen; // Pass `true` if this is the login screen // final bool isLoginScreen; // Pass `true` if this is the login screen
@ -35,6 +39,7 @@ class LoginRoute extends HookConsumerWidget {
LoginRoute({super.key}); LoginRoute({super.key});
dynamic userData; dynamic userData;
String? role; String? role;
int? loginCount;
static final formKey = GlobalKey<FormState>(); static final formKey = GlobalKey<FormState>();
@ -83,11 +88,41 @@ class LoginRoute extends HookConsumerWidget {
} }
} }
Future<void> saveUserId(String userId) async { Future<void> saveUserId(String userId, count) async {
print(count);
final prefs = await SharedPreferences.getInstance(); final prefs = await SharedPreferences.getInstance();
await prefs.setString('userId', userId); // Save userId locally await prefs.setString('userId', userId); // Save userId locally
await prefs.setString('login_count', count.toString());
} }
// Future<void> 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 @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final locale = ref.watch(localeProvider); final locale = ref.watch(localeProvider);
@ -305,6 +340,10 @@ class LoginRoute extends HookConsumerWidget {
if (response.statusCode == 200) { if (response.statusCode == 200) {
print("Login success API call successful: ${response.body}"); 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 { } else {
print( print(
"Failed to call login success API. Status code: ${response.statusCode}"); "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"); print("Error calling login success API: $e");
} }
await saveUserId(userId); await saveUserId(userId, loginCount);
} }
try { try {
final bool isProfileComplete = await profileStatus(userId); final bool isProfileComplete = await profileStatus(userId);

View File

@ -233,6 +233,7 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
print('render finished'); print('render finished');
_showHomeTour(); _showHomeTour();
} else { } else {
print('render delayed');
Future.delayed(Duration(milliseconds: 100), _starTourRender); Future.delayed(Duration(milliseconds: 100), _starTourRender);
} }
} }
@ -804,7 +805,19 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
super.initState(); super.initState();
final locale = ref.read(localeProvider); final locale = ref.read(localeProvider);
fetchData(locale?.languageCode ?? 'en'); fetchData(locale?.languageCode ?? 'en');
_fetchUserData(); // _fetchUserData();
_loadLoginCount();
}
Future<void> _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 // @override
@ -820,33 +833,35 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
return prefs.getString('userId'); // Retrieve the userId return prefs.getString('userId'); // Retrieve the userId
} }
Future<void> _fetchUserData() async { // Future<void> _fetchUserData() async {
try { // try {
final userId = await getUserId(); // final userId = await getUserId();
print('EDIT PROFILE isPageLoad'); // print('EDIT PROFILE isPageLoad');
final adminAuth = await _pb.admins // final adminAuth = await _pb.admins
.authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com'); // .authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com');
final adminToken = adminAuth.token; // final adminToken = adminAuth.token;
print('adminToken- $adminToken'); // print('adminToken- $adminToken');
final userDetailsResponse = await _pb.collection('users').getOne( // final userDetailsResponse = await _pb.collection('users').getOne(
userId!, // userId!,
headers: { // headers: {
'Authorization': 'Bearer $adminToken', // 'Authorization': 'Bearer $adminToken',
}, // },
); // );
final loginCount = userDetailsResponse.data['login_count']; // final loginCount = userDetailsResponse.data['login_count'];
print(loginCount); // print(loginCount);
if (loginCount == 1) { // if (loginCount == 1) {
setState(() { // print('_starTourRender count 1');
WidgetsBinding.instance.addPostFrameCallback((_) { // setState(() {
_starTourRender(); // print('_starTourRender');
}); // WidgetsBinding.instance.addPostFrameCallback((_) {
}); // _starTourRender();
} // });
} catch (e) { // });
print('Error fetching user details: $e'); // }
} // } catch (e) {
} // print('Error fetching user details: $e');
// }
// }
Future<void> fetchData(locale) async { Future<void> fetchData(locale) async {
const baseUrl = 'https://pb.venbait.in/api/getHomePageData'; const baseUrl = 'https://pb.venbait.in/api/getHomePageData';

View File

@ -4,12 +4,15 @@ import 'dart:convert';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.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:go_router/go_router.dart';
import 'package:package_info_plus/package_info_plus.dart'; import 'package:package_info_plus/package_info_plus.dart';
import 'package:pocketbase/pocketbase.dart'; import 'package:pocketbase/pocketbase.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:tutorial_coach_mark/tutorial_coach_mark.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/bottom_bar_asset_icon_path.dart';
import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/drawer_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<BaseScaffold> {
final GlobalKey drawerKey = GlobalKey(); final GlobalKey drawerKey = GlobalKey();
late double toggleHeight = 0; late double toggleHeight = 0;
bool isLoggedOut = false; bool isLoggedOut = false;
final FlutterSecureStorage _secureStorage = const FlutterSecureStorage();
static final _repo = getIt.call<TAuthRepo>();
@override @override
void initState() { void initState() {
@ -197,7 +202,8 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
.read(previousChartsTourProvider .read(previousChartsTourProvider
.notifier) .notifier)
.state = false; .state = false;
context.go('/chartScreen/hotels?bgColor=0xFF90B0D5&mainTopic=ECONOMY&title=Hotel+Establishments'); context.go(
'/chartScreen/hotels?bgColor=0xFF90B0D5&mainTopic=ECONOMY&title=Hotel+Establishments');
}, },
), ),
), ),
@ -335,8 +341,7 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
), ),
), ),
TargetContent( TargetContent(
padding: EdgeInsets.only( padding: EdgeInsets.only(right: screenWidth * 0.7, top: 30),
right: screenWidth * 0.7, top: 30),
align: ContentAlign.right, align: ContentAlign.right,
child: Container( child: Container(
width: 200, width: 200,
@ -593,8 +598,13 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
// setState(() { // setState(() {
// isLoggedOut = true; // isLoggedOut = true;
// }); // });
// prefs.clear();
await _repo.logout();
// state = const AsyncData(null);
// _pb.authStore.clear();
// await _secureStorage.delete(key: "FlutterSecureStorage.session");
prefs.clear(); prefs.clear();
context.go('/'); context.go('/login');
} }
@override @override
@ -834,50 +844,66 @@ leading: Image.asset(
items: [ items: [
BottomNavigationBarItem( BottomNavigationBarItem(
icon: Padding( icon: Padding(
padding: const EdgeInsets.only(bottom: 4), // Adjust this for spacing padding:
const EdgeInsets.only(bottom: 4), // Adjust this for spacing
child: Image.asset( child: Image.asset(
BottomBarAssetIconPath.home, BottomBarAssetIconPath.home,
color: _getSelectedIndex(currentRoute) == 0 ? Colors.black : Color(0xFF989898), color: _getSelectedIndex(currentRoute) == 0
? Colors.black
: Color(0xFF989898),
width: 20, width: 20,
height: 20, height: 20,
),), ),
),
// label: 'Home', // label: 'Home',
label: AppLocalizations.of(context)!.nav_home, label: AppLocalizations.of(context)!.nav_home,
), ),
BottomNavigationBarItem( BottomNavigationBarItem(
// icon: Icon(Icons.map), // icon: Icon(Icons.map),
icon: Padding( icon: Padding(
padding: const EdgeInsets.only(bottom: 4), // Adjust this for spacing padding:
const EdgeInsets.only(bottom: 4), // Adjust this for spacing
child: Image.asset( child: Image.asset(
BottomBarAssetIconPath.uaeMap, BottomBarAssetIconPath.uaeMap,
color: _getSelectedIndex(currentRoute) == 1 ? Colors.black : Color(0xFF989898), color: _getSelectedIndex(currentRoute) == 1
? Colors.black
: Color(0xFF989898),
width: 20, width: 20,
height: 20, height: 20,
),), ),
),
// label: 'UAE Numbers' // label: 'UAE Numbers'
label: AppLocalizations.of(context)!.nav_uae, label: AppLocalizations.of(context)!.nav_uae,
), ),
BottomNavigationBarItem( BottomNavigationBarItem(
icon: Padding( icon: Padding(
padding: const EdgeInsets.only(bottom: 4), // Adjust this for spacing padding:
const EdgeInsets.only(bottom: 4), // Adjust this for spacing
child: Image.asset( child: Image.asset(
BottomBarAssetIconPath.ranking, BottomBarAssetIconPath.ranking,
color: _getSelectedIndex(currentRoute) == 2 ? Colors.black : Color(0xFF989898), color: _getSelectedIndex(currentRoute) == 2
? Colors.black
: Color(0xFF989898),
width: 20, width: 20,
height: 20, height: 20,
),), ),
),
// label: 'Competitiveness', // label: 'Competitiveness',
label: AppLocalizations.of(context)!.nav_competitiveness, label: AppLocalizations.of(context)!.nav_competitiveness,
), ),
BottomNavigationBarItem( BottomNavigationBarItem(
icon: Padding( icon: Padding(
padding: const EdgeInsets.only(bottom: 4), // Adjust this for spacing padding:
const EdgeInsets.only(bottom: 4), // Adjust this for spacing
child: Image.asset( child: Image.asset(
BottomBarAssetIconPath.globe, BottomBarAssetIconPath.globe,
color: _getSelectedIndex(currentRoute) == 2 ? Colors.black : Color(0xFF989898), color: _getSelectedIndex(currentRoute) == 2
? Colors.black
: Color(0xFF989898),
width: 20, width: 20,
height: 20, height: 20,
),), ),
),
// label: 'Country Profile', // label: 'Country Profile',
label: AppLocalizations.of(context)!.country_profile, label: AppLocalizations.of(context)!.country_profile,
), ),