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_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<String> getInitialRoute() async {
bool isLoggedIn = await pbService.loadSession();
return isLoggedIn ? '/myhomepage' : '/login';
Future<String?> _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(),

View File

@ -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<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();
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
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);

View File

@ -233,6 +233,7 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
print('render finished');
_showHomeTour();
} else {
print('render delayed');
Future.delayed(Duration(milliseconds: 100), _starTourRender);
}
}
@ -804,7 +805,19 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
super.initState();
final locale = ref.read(localeProvider);
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
@ -820,33 +833,35 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
return prefs.getString('userId'); // Retrieve the userId
}
Future<void> _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<void> _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<void> fetchData(locale) async {
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/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<BaseScaffold> {
final GlobalKey drawerKey = GlobalKey();
late double toggleHeight = 0;
bool isLoggedOut = false;
final FlutterSecureStorage _secureStorage = const FlutterSecureStorage();
static final _repo = getIt.call<TAuthRepo>();
@override
void initState() {
@ -145,7 +150,7 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
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<BaseScaffold> {
.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<BaseScaffold> {
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<BaseScaffold> {
),
),
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<BaseScaffold> {
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<BaseScaffold> {
.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<BaseScaffold> {
.state = true;
ref
.read(previousScaffoldTourProvider
.notifier)
.notifier)
.state = true;
tutorialCoachMark.finish();
},
@ -496,7 +501,7 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
),
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<BaseScaffold> {
// 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<BaseScaffold> {
ListTile(
leading: Image.asset(
DrawerAssetIconPath.feedback,
color: Colors.black ,
color: Colors.black,
width: 20,
height: 20,
),
@ -747,13 +757,13 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
),
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,
),
],