fixed the tennt selection process

This commit is contained in:
Vaibhav Surve 2025-10-08 16:07:26 +05:30
parent d1d48b1a74
commit 041b62ca2f
11 changed files with 43 additions and 72 deletions

View File

@ -81,7 +81,7 @@ class LoginController extends MyController {
logSafe("Login successful for user: ${loginData['username']}");
Get.toNamed('/select_tenant');
Get.toNamed('/select-tenant');
}
} catch (e, stacktrace) {
logSafe("Exception during login",

View File

@ -4,7 +4,6 @@ import 'package:marco/helpers/services/auth_service.dart';
import 'package:marco/helpers/services/storage/local_storage.dart';
import 'package:marco/helpers/widgets/my_form_validator.dart';
import 'package:marco/helpers/widgets/my_snackbar.dart';
import 'package:marco/view/dashboard/dashboard_screen.dart';
import 'package:marco/helpers/services/app_logger.dart';
import 'package:marco/helpers/services/firebase/firebase_messaging_service.dart';
import 'package:marco/controller/permission_controller.dart';
@ -140,16 +139,17 @@ class MPINController extends GetxController {
}
/// Navigate to dashboard
void _navigateToDashboard({String? message}) {
/// Navigate to tenant selection after MPIN verification
void _navigateToTenantSelection({String? message}) {
if (message != null) {
logSafe("Navigating to Dashboard with message: $message");
logSafe("Navigating to Tenant Selection with message: $message");
showAppSnackbar(
title: "Success",
message: message,
type: SnackbarType.success,
);
}
Get.offAll(() => const DashboardScreen());
Get.offAllNamed('/select-tenant');
}
/// Clear the primary MPIN fields
@ -287,7 +287,7 @@ class MPINController extends GetxController {
message: "MPIN Verified Successfully",
type: SnackbarType.success,
);
_navigateToDashboard();
_navigateToTenantSelection();
} else {
final errorMessage = response["error"] ?? "Invalid MPIN";
logSafe("MPIN verification failed: $errorMessage",

View File

@ -109,7 +109,8 @@ class OTPController extends GetxController {
}
void onOTPChanged(String value, int index) {
logSafe("[OTPController] OTP field changed: index=$index", level: LogLevel.debug);
logSafe("[OTPController] OTP field changed: index=$index",
level: LogLevel.debug);
if (value.isNotEmpty) {
if (index < otpControllers.length - 1) {
focusNodes[index + 1].requestFocus();
@ -125,30 +126,24 @@ class OTPController extends GetxController {
Future<void> verifyOTP() async {
final enteredOTP = otpControllers.map((c) => c.text).join();
logSafe("[OTPController] Verifying OTP");
final result = await AuthService.verifyOtp(
email: email.value,
otp: enteredOTP,
);
if (result == null) {
logSafe("[OTPController] OTP verified successfully");
showAppSnackbar(
title: "Success",
message: "OTP verified successfully",
type: SnackbarType.success,
);
final bool isMpinEnabled = LocalStorage.getIsMpin();
logSafe("[OTPController] MPIN Enabled: $isMpinEnabled");
// Handle remember-me like in LoginController
final remember = LocalStorage.getBool('remember_me') ?? false;
if (remember) await LocalStorage.setToken('otp_email', email.value);
Get.offAllNamed('/home');
// Enable remote logging
enableRemoteLogging();
Get.offAllNamed('/select-tenant');
} else {
final error = result['error'] ?? "Failed to verify OTP";
logSafe("[OTPController] OTP verification failed", level: LogLevel.warning, error: error);
showAppSnackbar(
title: "Error",
message: error,
message: result['error']!,
type: SnackbarType.error,
);
}
@ -215,7 +210,8 @@ class OTPController extends GetxController {
final savedEmail = LocalStorage.getToken('otp_email') ?? '';
emailController.text = savedEmail;
email.value = savedEmail;
logSafe("[OTPController] Loaded saved email from local storage: $savedEmail");
logSafe(
"[OTPController] Loaded saved email from local storage: $savedEmail");
}
}
}

View File

@ -49,8 +49,8 @@ class ResetPasswordController extends MyController {
basicValidator.clearErrors();
}
logSafe("[ResetPasswordController] Navigating to /home");
Get.toNamed('/home');
logSafe("[ResetPasswordController] Navigating to /dashboard");
Get.toNamed('/dashboard');
update();
} else {
logSafe("[ResetPasswordController] Form validation failed", level: LogLevel.warning);

View File

@ -1,9 +1,5 @@
import 'dart:convert';
import 'package:get/get.dart';
import 'package:http/http.dart' as http;
import 'package:marco/controller/permission_controller.dart';
import 'package:marco/controller/project_controller.dart';
import 'package:marco/helpers/services/api_endpoints.dart';
import 'package:marco/helpers/services/storage/local_storage.dart';
import 'package:marco/helpers/services/app_logger.dart';
@ -98,8 +94,8 @@ class AuthService {
}
static Future<bool> refreshToken() async {
final accessToken = await LocalStorage.getJwtToken();
final refreshToken = await LocalStorage.getRefreshToken();
final accessToken = LocalStorage.getJwtToken();
final refreshToken = LocalStorage.getRefreshToken();
if ([accessToken, refreshToken].any((t) => t == null || t.isEmpty)) {
logSafe("Missing access or refresh token.", level: LogLevel.warning);
@ -115,7 +111,7 @@ class AuthService {
logSafe("Token refreshed successfully.");
// 🔹 Retry FCM token registration after token refresh
final newFcmToken = await LocalStorage.getFcmToken();
final newFcmToken = LocalStorage.getFcmToken();
if (newFcmToken?.isNotEmpty ?? false) {
final success = await registerDeviceToken(newFcmToken!);
logSafe(
@ -157,7 +153,7 @@ class AuthService {
}) =>
_wrapErrorHandling(
() async {
final token = await LocalStorage.getJwtToken();
final token = LocalStorage.getJwtToken();
return _post(
"/auth/generate-mpin",
{"employeeId": employeeId, "mpin": mpin},
@ -290,36 +286,6 @@ class AuthService {
await LocalStorage.setIsMpin(false);
await LocalStorage.removeMpinToken();
}
// 🔹 Inject controllers only here, after login success
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
final token = data['token'];
await Future.wait([
Get.find<PermissionController>().loadData(token),
Get.find<ProjectController>().fetchProjects(),
]);
// 🔹 Register FCM token after login
final fcmToken = await LocalStorage.getFcmToken();
if (fcmToken?.isNotEmpty ?? false) {
final success = await registerDeviceToken(fcmToken!);
logSafe(
success
? "✅ FCM token registered after login."
: "⚠️ Failed to register FCM token after login.",
level: success ? LogLevel.info : LogLevel.warning);
}
isLoggedIn = true;
logSafe("✅ Login flow completed and controllers initialized.");
}

View File

@ -19,7 +19,7 @@ class FirebaseNotificationService {
_registerMessageListeners();
_registerTokenRefreshListener();
// Fetch token on app start (but only register with server if JWT available)
// Fetch token on app start (and register with server if JWT available)
await getFcmToken(registerOnServer: true);
}
@ -49,6 +49,7 @@ class FirebaseNotificationService {
FirebaseMessaging.onMessageOpenedApp.listen(_handleNotificationTap);
// Background messages
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
}
@ -111,8 +112,6 @@ class FirebaseNotificationService {
}
}
/// Handle tap on notification
void _handleNotificationTap(RemoteMessage message) {
_logger.i('📌 Notification tapped: ${message.data}');
@ -129,7 +128,9 @@ class FirebaseNotificationService {
}
}
/// Background handler (required by Firebase)
/// 🔹 Background handler (required by Firebase)
/// Must be a top-level function and annotated for AOT
@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
final logger = Logger();
logger

View File

@ -129,6 +129,17 @@ class TenantService implements ITenantService {
logSafe("⚠️ ProjectController not found while refreshing projects");
}
// 🔹 Register FCM token after tenant selection
final fcmToken = LocalStorage.getFcmToken();
if (fcmToken?.isNotEmpty ?? false) {
final success = await AuthService.registerDeviceToken(fcmToken!);
logSafe(
success
? "✅ FCM token registered after tenant selection."
: "⚠️ Failed to register FCM token after tenant selection.",
level: success ? LogLevel.info : LogLevel.warning);
}
return true;
}

View File

@ -230,7 +230,7 @@ class AppStyle {
containerRadius: AppStyle.containerRadius.medium,
cardRadius: AppStyle.cardRadius.medium,
buttonRadius: AppStyle.buttonRadius.medium,
defaultBreadCrumbItem: MyBreadcrumbItem(name: 'Marco', route: '/client/home'),
defaultBreadCrumbItem: MyBreadcrumbItem(name: 'Marco', route: '/client/dashboard'),
));
bool isMobile = true;
try {

View File

@ -45,7 +45,7 @@ getPageRoute() {
page: () => DashboardScreen(),
middlewares: [AuthMiddleware()]),
GetPage(
name: '/home',
name: '/dashboard',
page: () => DashboardScreen(), // or your actual home screen
middlewares: [AuthMiddleware()],
),

View File

@ -82,7 +82,7 @@ class _LeftBarState extends State<LeftBar>
child: Padding(
padding: EdgeInsets.only(top: 50),
child: InkWell(
onTap: () => Get.toNamed('/home'),
onTap: () => Get.toNamed('/dashboard'),
child: Image.asset(
(ThemeCustomizer.instance.theme == ThemeMode.light
? (widget.isCondensed

View File

@ -209,9 +209,6 @@ class TenantCardList extends StatelessWidget {
),
);
}
if (controller.tenants.length == 1) {
return const SizedBox.shrink();
}
// Show tenant even if only 1 tenant
return SingleChildScrollView(
padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 24),