marco.pms.mobileapp/lib/controller/tenant/tenant_selection_controller.dart
2025-10-08 11:06:39 +05:30

134 lines
4.2 KiB
Dart

import 'package:get/get.dart';
import 'package:marco/helpers/services/app_logger.dart';
import 'package:marco/helpers/services/tenant_service.dart';
import 'package:marco/model/tenant/tenant_list_model.dart';
import 'package:marco/helpers/widgets/my_snackbar.dart';
import 'package:marco/helpers/services/storage/local_storage.dart';
import 'package:marco/controller/permission_controller.dart';
class TenantSelectionController extends GetxController {
final TenantService _tenantService = TenantService();
TenantSelectionController();
final tenants = <Tenant>[].obs;
final isLoading = false.obs;
final selectedTenantId = RxnString();
@override
void onInit() {
super.onInit();
loadTenants();
}
/// Load tenants and perform smart auto-selection
Future<void> loadTenants() async {
isLoading.value = true;
try {
final data = await _tenantService.getTenants();
if (data == null || data.isEmpty) {
tenants.clear();
logSafe("⚠️ No tenants found for the user.", level: LogLevel.warning);
return;
}
tenants.value = data.map((e) => Tenant.fromJson(e)).toList();
// Smart auto-selection
final recentTenantId = await LocalStorage.getRecentTenantId();
if (tenants.length == 1) {
await _selectTenant(tenants.first.id);
} else if (recentTenantId != null) {
final recentTenant =
tenants.where((t) => t.id == recentTenantId).isNotEmpty
? tenants.firstWhere((t) => t.id == recentTenantId)
: null;
if (recentTenant != null) {
await _selectTenant(recentTenant.id);
} else {
selectedTenantId.value = null;
TenantService.currentTenant = null;
}
} else {
selectedTenantId.value = null;
TenantService.currentTenant = null;
}
} catch (e, st) {
logSafe("❌ Exception in loadTenants",
level: LogLevel.error, error: e, stackTrace: st);
showAppSnackbar(
title: "Error",
message: "Failed to load organizations. Please try again.",
type: SnackbarType.error,
);
} finally {
isLoading.value = false;
}
}
/// Manually select tenant (user triggered)
Future<void> onTenantSelected(String tenantId) async {
await _selectTenant(tenantId);
}
/// Internal tenant selection logic
Future<void> _selectTenant(String tenantId) async {
try {
isLoading.value = true;
final success = await _tenantService.selectTenant(tenantId);
if (!success) {
logSafe("❌ Tenant selection failed for: $tenantId",
level: LogLevel.warning);
showAppSnackbar(
title: "Error",
message: "Unable to select organization. Please try again.",
type: SnackbarType.error,
);
return;
}
final selectedTenant = tenants.firstWhere((t) => t.id == tenantId);
TenantService.setSelectedTenant(selectedTenant);
selectedTenantId.value = tenantId;
// Persist recent tenant
await LocalStorage.setRecentTenantId(tenantId);
logSafe("✅ Tenant selection successful: $tenantId");
// 🔹 Load permissions after tenant selection (null-safe)
final token = await LocalStorage.getJwtToken();
if (token != null && token.isNotEmpty) {
if (!Get.isRegistered<PermissionController>()) {
Get.put(PermissionController());
logSafe("✅ PermissionController injected after tenant selection.");
}
await Get.find<PermissionController>().loadData(token);
} else {
logSafe("⚠️ JWT token is null. Cannot load permissions.", level: LogLevel.warning);
}
// Navigate to dashboard
Get.offAllNamed('/dashboard');
showAppSnackbar(
title: "Success",
message: "Organization selected successfully.",
type: SnackbarType.success,
);
} catch (e, st) {
logSafe("❌ Exception in _selectTenant",
level: LogLevel.error, error: e, stackTrace: st);
showAppSnackbar(
title: "Error",
message: "An unexpected error occurred while selecting organization.",
type: SnackbarType.error,
);
} finally {
isLoading.value = false;
}
}
}