From c9a3805819e05067200303d81bad98c1c21c9317 Mon Sep 17 00:00:00 2001 From: Vaibhav Surve Date: Sat, 26 Apr 2025 12:27:31 +0530 Subject: [PATCH] implemented permision controller functionallity --- lib/controller/permission_controller.dart | 100 ++++++++++++++++++ lib/helpers/services/permission_service.dart | 44 ++++++++ .../services/storage/local_storage.dart | 31 +++++- lib/helpers/utils/permission_constants.dart | 11 ++ lib/main.dart | 8 +- lib/model/user_permission.dart | 19 ++++ 6 files changed, 210 insertions(+), 3 deletions(-) create mode 100644 lib/controller/permission_controller.dart create mode 100644 lib/helpers/services/permission_service.dart create mode 100644 lib/helpers/utils/permission_constants.dart create mode 100644 lib/model/user_permission.dart diff --git a/lib/controller/permission_controller.dart b/lib/controller/permission_controller.dart new file mode 100644 index 0000000..71dd740 --- /dev/null +++ b/lib/controller/permission_controller.dart @@ -0,0 +1,100 @@ +import 'dart:async'; +import 'dart:convert'; +import 'package:get/get.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:marco/helpers/services/permission_service.dart'; +import 'package:marco/model/user_permission.dart'; + +class PermissionController extends GetxController { + var permissions = [].obs; + Timer? _refreshTimer; + + @override + void onInit() { + super.onInit(); + _loadStoredPermissions(); // Try to load from local storage first + _startAutoRefresh(); // Schedule auto-refresh every 15 minutes + } + + // Load permissions from SharedPreferences + Future _loadStoredPermissions() async { + final prefs = await SharedPreferences.getInstance(); + final storedJson = prefs.getString('user_permissions'); + + if (storedJson != null) { + print("Loaded Permissions from SharedPreferences: $storedJson"); + try { + final List parsedList = jsonDecode(storedJson); + + permissions.assignAll( + parsedList + .map((e) => UserPermission.fromJson(e as Map)) + .toList(), + ); + } catch (e) { + print("Error decoding stored permissions: $e"); + await prefs.remove('user_permissions'); + await _loadPermissionsFromAPI(); // fallback to API load + } + } else { + // If no permissions stored, fallback to API + await _loadPermissionsFromAPI(); + } + } + + // Save permissions to SharedPreferences + Future _storePermissions() async { + final prefs = await SharedPreferences.getInstance(); + final jsonList = permissions.map((e) => e.toJson()).toList(); + print("Storing Permissions: $jsonList"); + await prefs.setString('user_permissions', jsonEncode(jsonList)); + } + + // Public method to load permissions (usually called from outside) + Future loadPermissions(String token) async { + try { + final result = await PermissionService.fetchPermissions(token); + print("Fetched Permissions from API: $result"); + + permissions.assignAll(result); // Update observable list + await _storePermissions(); // Cache locally + } catch (e) { + print('Error loading permissions from API: $e'); + } + } + + // Internal helper to load token and fetch permissions from API + Future _loadPermissionsFromAPI() async { + final token = await _getAuthToken(); + if (token != null && token.isNotEmpty) { + await loadPermissions(token); + } else { + print("No token available for fetching permissions."); + } + } + + // Retrieve token from SharedPreferences + Future _getAuthToken() async { + final prefs = await SharedPreferences.getInstance(); + return prefs.getString( + 'jwt_token'); // Or 'auth_token' if that’s the key you're using + } + + // Auto-refresh every 15 minutes + void _startAutoRefresh() { + _refreshTimer = Timer.periodic(Duration(minutes: 30), (timer) async { + await _loadPermissionsFromAPI(); + }); + } + + // Check for specific permission + bool hasPermission(String permissionId) { + return permissions.any((p) => p.id == permissionId); + } + + @override + void onClose() { + _refreshTimer?.cancel(); + super.onClose(); + } +} diff --git a/lib/helpers/services/permission_service.dart b/lib/helpers/services/permission_service.dart new file mode 100644 index 0000000..d4182d2 --- /dev/null +++ b/lib/helpers/services/permission_service.dart @@ -0,0 +1,44 @@ +import 'package:http/http.dart' as http; +import 'dart:convert'; +import 'package:marco/model/user_permission.dart'; + +class PermissionService { + static Future> fetchPermissions(String token) async { + try { + final response = await http.get( + Uri.parse('https://api.marcoaiot.com/api/user/profile'), + headers: {'Authorization': 'Bearer $token'}, + ); + + // Print the full response for debugging + print('Status Code: ${response.statusCode}'); + print('Response Body: ${response.body}'); + + if (response.statusCode == 200) { + final decoded = json.decode(response.body); + + // Debug the decoded data + print('Decoded Data: $decoded'); + + // Extract featurePermissions + final List featurePermissions = + decoded['data']['featurePermissions']; + + // Check if the featurePermissions are indeed a List of Strings + print('FeaturePermissions Type: ${featurePermissions.runtimeType}'); + + // Map the featurePermissions to UserPermission objects + return featurePermissions + .map( + (permissionId) => UserPermission.fromJson({'id': permissionId})) + .toList(); + } else { + final errorData = json.decode(response.body); + throw Exception('Failed to load permissions: ${errorData['message']}'); + } + } catch (e) { + print('Error fetching permissions: $e'); + throw Exception('Error fetching permissions: $e'); + } + } +} diff --git a/lib/helpers/services/storage/local_storage.dart b/lib/helpers/services/storage/local_storage.dart index 1408585..7837298 100644 --- a/lib/helpers/services/storage/local_storage.dart +++ b/lib/helpers/services/storage/local_storage.dart @@ -2,7 +2,8 @@ import 'package:marco/helpers/services/auth_service.dart'; import 'package:marco/helpers/services/localizations/language.dart'; import 'package:marco/helpers/theme/theme_customizer.dart'; import 'package:shared_preferences/shared_preferences.dart'; - +import 'package:marco/model/user_permission.dart'; +import 'dart:convert'; class LocalStorage { static const String _loggedInUserKey = "user"; static const String _themeCustomizerKey = "theme_customizer"; @@ -18,6 +19,34 @@ class LocalStorage { } return _preferencesInstance!; } +// In LocalStorage class + static const String _userPermissionsKey = "user_permissions"; + + static Future setUserPermissions( + List permissions) async { + // Convert the list of UserPermission objects to a List> + final jsonList = permissions.map((e) => e.toJson()).toList(); + + // Save as a JSON string + return preferences.setString(_userPermissionsKey, jsonEncode(jsonList)); + } + + static List getUserPermissions() { + final storedJson = preferences.getString(_userPermissionsKey); + + if (storedJson != null) { + final List parsedList = jsonDecode(storedJson); + return parsedList + .map((e) => UserPermission.fromJson(e as Map)) + .toList(); + } + + return []; // Return empty list if no permissions are found + } + + static Future removeUserPermissions() async { + return preferences.remove(_userPermissionsKey); + } static Future init() async { _preferencesInstance = await SharedPreferences.getInstance(); diff --git a/lib/helpers/utils/permission_constants.dart b/lib/helpers/utils/permission_constants.dart new file mode 100644 index 0000000..230f161 --- /dev/null +++ b/lib/helpers/utils/permission_constants.dart @@ -0,0 +1,11 @@ +class Permissions { + static const String manageMaster = "588a8824-f924-4955-82d8-fc51956cf323"; + static const String manageProject = "172fc9b6-755b-4f62-ab26-55c34a330614"; + static const String viewProjects = "6ea44136-987e-44ba-9e5d-1cf8f5837ebc"; + static const String manageEmployees = "a97d366a-c2bb-448d-be93-402bd2324566"; + static const String manageProjectInfra = "f2aee20a-b754-4537-8166-f9507b44585b"; + static const String viewProjectInfra = "c7b68e33-72f0-474f-bd96-77636427ecc8"; + static const String regularizeAttendance = "57802c4a-00aa-4a1f-a048-fd2f70dd44b6"; + static const String assignToProject = "fbd213e0-0250-46f1-9f5f-4b2a1e6e76a3"; + static const String infrastructure = "9666de86-d7c7-4d3d-acaa-fcd6d6b81f3c"; +} diff --git a/lib/main.dart b/lib/main.dart index 0d0259c..46ee421 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -11,7 +11,7 @@ import 'package:marco/helpers/theme/theme_customizer.dart'; import 'package:marco/routes.dart'; import 'package:provider/provider.dart'; import 'package:url_strategy/url_strategy.dart'; - +import 'package:marco/controller/permission_controller.dart'; Future main() async { WidgetsFlutterBinding.ensureInitialized(); setPathUrlStrategy(); @@ -19,9 +19,11 @@ Future main() async { await LocalStorage.init(); AppStyle.init(); await ThemeCustomizer.init(); + Get.put(PermissionController()); runApp(ChangeNotifierProvider( create: (context) => AppNotifier(), child: MyApp(), + )); } @@ -42,7 +44,9 @@ class MyApp extends StatelessWidget { getPages: getPageRoute(), builder: (context, child) { NavigationService.registerContext(context); - return Directionality(textDirection: AppTheme.textDirection, child: child ?? Container()); + return Directionality( + textDirection: AppTheme.textDirection, + child: child ?? Container()); }, localizationsDelegates: [ AppLocalizationsDelegate(context), diff --git a/lib/model/user_permission.dart b/lib/model/user_permission.dart new file mode 100644 index 0000000..27abd3a --- /dev/null +++ b/lib/model/user_permission.dart @@ -0,0 +1,19 @@ +class UserPermission { + final String id; + + UserPermission({required this.id}); + + // Deserialize from JSON + factory UserPermission.fromJson(Map json) { + return UserPermission( + id: json['id'], // Only the 'id' field is needed + ); + } + + // Serialize to JSON + Map toJson() { + return { + 'id': id, // Only include 'id' when converting to JSON + }; + } +}