feat(auth): refactor login success flow to inject controllers and load data conditionally

This commit is contained in:
Vaibhav Surve 2025-07-09 15:48:15 +05:30
parent ffba37b767
commit 5b5030ec36
4 changed files with 106 additions and 79 deletions

View File

@ -2,7 +2,7 @@ import 'dart:async';
import 'dart:convert';
import 'package:get/get.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:marco/helpers/services/app_logger.dart';
import 'package:marco/helpers/services/app_logger.dart';
import 'package:marco/helpers/services/permission_service.dart';
import 'package:marco/model/user_permission.dart';
import 'package:marco/model/employee_info.dart';
@ -17,8 +17,51 @@ class PermissionController extends GetxController {
@override
void onInit() {
super.onInit();
_loadDataFromAPI();
_startAutoRefresh();
_initialize();
}
Future<void> _initialize() async {
final token = await _getAuthToken();
if (token?.isNotEmpty ?? false) {
await loadData(token!);
_startAutoRefresh();
} else {
logSafe("Token is null or empty. Skipping API load and auto-refresh.", level: LogLevel.warning);
}
}
Future<String?> _getAuthToken() async {
try {
final prefs = await SharedPreferences.getInstance();
final token = prefs.getString('jwt_token');
logSafe("Auth token retrieved: $token", level: LogLevel.debug);
return token;
} catch (e, stacktrace) {
logSafe("Error retrieving auth token", level: LogLevel.error, error: e, stackTrace: stacktrace);
return null;
}
}
Future<void> loadData(String token) async {
try {
final userData = await PermissionService.fetchAllUserData(token);
_updateState(userData);
await _storeData();
logSafe("Data loaded and state updated successfully.");
} catch (e, stacktrace) {
logSafe("Error loading data from API", level: LogLevel.error, error: e, stackTrace: stacktrace);
}
}
void _updateState(Map<String, dynamic> userData) {
try {
permissions.assignAll(userData['permissions']);
employeeInfo.value = userData['employeeInfo'];
projectsInfo.assignAll(userData['projects']);
logSafe("State updated with user data.");
} catch (e, stacktrace) {
logSafe("Error updating state", level: LogLevel.error, error: e, stackTrace: stacktrace);
}
}
Future<void> _storeData() async {
@ -50,54 +93,15 @@ class PermissionController extends GetxController {
}
}
Future<void> _loadDataFromAPI() async {
final token = await _getAuthToken();
if (token?.isNotEmpty ?? false) {
await loadData(token!);
} else {
logSafe("No token found for loading API data.", level: LogLevel.warning);
}
}
Future<void> loadData(String token) async {
try {
final userData = await PermissionService.fetchAllUserData(token);
_updateState(userData);
await _storeData();
logSafe("Data loaded and state updated successfully.");
} catch (e, stacktrace) {
logSafe("Error loading data from API", level: LogLevel.error, error: e, stackTrace: stacktrace);
}
}
void _updateState(Map<String, dynamic> userData) {
try {
permissions.assignAll(userData['permissions']);
employeeInfo.value = userData['employeeInfo'];
projectsInfo.assignAll(userData['projects']);
logSafe("State updated with new user data.", );
} catch (e, stacktrace) {
logSafe("Error updating state", level: LogLevel.error, error: e, stackTrace: stacktrace);
}
}
Future<String?> _getAuthToken() async {
try {
final prefs = await SharedPreferences.getInstance();
final token = prefs.getString('jwt_token');
logSafe("Auth token retrieved successfully.", );
return token;
} catch (e, stacktrace) {
logSafe("Error retrieving auth token", level: LogLevel.error, error: e, stackTrace: stacktrace);
return null;
}
}
void _startAutoRefresh() {
_refreshTimer = Timer.periodic(Duration(minutes: 30), (timer) async {
logSafe("Auto-refresh triggered.");
await _loadDataFromAPI();
final token = await _getAuthToken();
if (token?.isNotEmpty ?? false) {
await loadData(token!);
} else {
logSafe("Token missing during auto-refresh. Skipping.", level: LogLevel.warning);
}
});
}
@ -116,7 +120,7 @@ class PermissionController extends GetxController {
@override
void onClose() {
_refreshTimer?.cancel();
logSafe("PermissionController disposed and timer cancelled.");
logSafe("PermissionController disposed and auto-refresh timer cancelled.");
super.onClose();
}
}

View File

@ -66,7 +66,7 @@ class ProjectController extends GetxController {
isProjectSelectionExpanded.value = false;
logSafe("Projects fetched: ${projects.length}");
} else {
logSafe("No projects found or API call failed.", level: LogLevel.warning);
logSafe("No Global projects found or API call failed.", level: LogLevel.warning);
}
isLoadingProjects.value = false;

View File

@ -27,18 +27,28 @@ Future<void> initializeApp() async {
await ThemeCustomizer.init();
logSafe("💡 Theme customizer initialized.");
Get.put(PermissionController());
logSafe("💡 PermissionController injected.");
final token = LocalStorage.getString('jwt_token');
if (token != null && token.isNotEmpty) {
if (!Get.isRegistered<PermissionController>()) {
Get.put(PermissionController());
logSafe("💡 PermissionController injected.");
}
Get.put(ProjectController(), permanent: true);
logSafe("💡 ProjectController injected as permanent.");
if (!Get.isRegistered<ProjectController>()) {
Get.put(ProjectController(), permanent: true);
logSafe("💡 ProjectController injected as permanent.");
}
} else {
logSafe("⚠️ No token found. Skipping PermissionController and ProjectController injection.");
}
AppStyle.init();
logSafe("💡 AppStyle initialized.");
logSafe("✅ App initialization completed successfully.");
} catch (e, stacktrace) {
logSafe("⛔ Error during app initialization",
logSafe(
"⛔ Error during app initialization",
level: LogLevel.error,
error: e,
stackTrace: stacktrace,

View File

@ -247,32 +247,45 @@ class AuthService {
}
/// Handle login success flow
static Future<void> _handleLoginSuccess(Map<String, dynamic> data) async {
logSafe("Processing login success...");
static Future<void> _handleLoginSuccess(Map<String, dynamic> data) async {
logSafe("Processing login success...");
final jwtToken = data['token'];
final refreshToken = data['refreshToken'];
final mpinToken = data['mpinToken'];
final jwtToken = data['token'];
final refreshToken = data['refreshToken'];
final mpinToken = data['mpinToken'];
await LocalStorage.setJwtToken(jwtToken);
await LocalStorage.setLoggedInUser(true);
// Save tokens
await LocalStorage.setJwtToken(jwtToken);
await LocalStorage.setLoggedInUser(true);
if (refreshToken != null) await LocalStorage.setRefreshToken(refreshToken);
if (mpinToken != null && mpinToken.isNotEmpty) {
await LocalStorage.setMpinToken(mpinToken);
await LocalStorage.setIsMpin(true);
} else {
await LocalStorage.setIsMpin(false);
await LocalStorage.removeMpinToken();
}
final permissionController = Get.put(PermissionController());
await permissionController.loadData(jwtToken);
await Get.find<ProjectController>().fetchProjects();
isLoggedIn = true;
logSafe("Login flow completed.");
if (refreshToken != null) {
await LocalStorage.setRefreshToken(refreshToken);
}
if (mpinToken != null && mpinToken.isNotEmpty) {
await LocalStorage.setMpinToken(mpinToken);
await LocalStorage.setIsMpin(true);
} else {
await LocalStorage.setIsMpin(false);
await LocalStorage.removeMpinToken();
}
// Inject controllers if not already registered
if (!Get.isRegistered<PermissionController>()) {
Get.put(PermissionController());
logSafe("✅ PermissionController injected after login.");
}
if (!Get.isRegistered<ProjectController>()) {
Get.put(ProjectController(), permanent: true);
logSafe("✅ ProjectController injected after login.");
}
// Load data into controllers
await Get.find<PermissionController>().loadData(jwtToken);
await Get.find<ProjectController>().fetchProjects();
isLoggedIn = true;
logSafe("✅ Login flow completed and controllers initialized.");
}
}