- Added image picking functionality using ImagePicker for selecting images from camera or gallery. - Refactored form field controllers in ReportTaskController for better management and disposal. - Updated reportTask and commentTask methods to use the new controller references. - Implemented image removal functionality in ReportTaskController. - Modified ReportTaskBottomSheet to clear fields upon initialization and added a callback for successful reports. - Updated attendance and regularization logs UI for better loading states and error handling. - Improved logout functionality in LocalStorage and integrated it into layout and left bar components. - Adjusted initial route logic in main.dart to redirect users based on authentication status.
83 lines
2.7 KiB
Dart
83 lines
2.7 KiB
Dart
import 'dart:convert';
|
|
import 'package:http/http.dart' as http;
|
|
import 'package:get/get.dart';
|
|
import 'package:logger/logger.dart';
|
|
import 'package:marco/model/user_permission.dart';
|
|
import 'package:marco/model/employee_info.dart';
|
|
import 'package:marco/model/projects_model.dart';
|
|
import 'package:marco/helpers/services/storage/local_storage.dart';
|
|
import 'package:marco/helpers/services/auth_service.dart';
|
|
|
|
final Logger logger = Logger();
|
|
|
|
class PermissionService {
|
|
static final Map<String, Map<String, dynamic>> _userDataCache = {};
|
|
|
|
static Future<Map<String, dynamic>> fetchAllUserData(String token,
|
|
{bool hasRetried = false}) async {
|
|
// Return from cache if available
|
|
if (_userDataCache.containsKey(token)) {
|
|
return _userDataCache[token]!;
|
|
}
|
|
|
|
try {
|
|
final response = await http.get(
|
|
Uri.parse('https://stageapi.marcoaiot.com/api/user/profile'),
|
|
headers: {'Authorization': 'Bearer $token'},
|
|
);
|
|
|
|
if (response.statusCode == 200) {
|
|
final data = json.decode(response.body)['data'];
|
|
|
|
final result = {
|
|
'permissions': _parsePermissions(data['featurePermissions']),
|
|
'employeeInfo': _parseEmployeeInfo(data['employeeInfo']),
|
|
'projects': _parseProjectsInfo(data['projects']),
|
|
};
|
|
|
|
_userDataCache[token] = result;
|
|
return result;
|
|
}
|
|
|
|
if (response.statusCode == 401 && !hasRetried) {
|
|
final refreshed = await AuthService.refreshToken();
|
|
if (refreshed) {
|
|
final newToken = await LocalStorage.getJwtToken();
|
|
if (newToken != null) {
|
|
return fetchAllUserData(newToken, hasRetried: true);
|
|
}
|
|
}
|
|
|
|
await _handleUnauthorized();
|
|
throw Exception('Unauthorized. Token refresh failed.');
|
|
}
|
|
|
|
final errorMessage =
|
|
json.decode(response.body)['message'] ?? 'Unknown error';
|
|
throw Exception('Failed to load data: $errorMessage');
|
|
} catch (e) {
|
|
logger.e('Error fetching user data: $e');
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
static Future<void> _handleUnauthorized() async {
|
|
await LocalStorage.removeToken('jwt_token');
|
|
await LocalStorage.removeToken('refresh_token');
|
|
await LocalStorage.setLoggedInUser(false);
|
|
Get.offAllNamed('/auth/login');
|
|
}
|
|
|
|
static List<UserPermission> _parsePermissions(
|
|
List<dynamic> featurePermissions) =>
|
|
featurePermissions
|
|
.map((id) => UserPermission.fromJson({'id': id}))
|
|
.toList();
|
|
|
|
static EmployeeInfo _parseEmployeeInfo(Map<String, dynamic> employeeData) =>
|
|
EmployeeInfo.fromJson(employeeData);
|
|
|
|
static List<ProjectInfo> _parseProjectsInfo(List<dynamic> projects) =>
|
|
projects.map((proj) => ProjectInfo.fromJson(proj)).toList();
|
|
}
|