using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using UtopiaCanteenSystem.Services; using UtopiaCanteenSystem.Services.Logging; namespace UtopiaCanteenSystem.ViewModels; public partial class AdminLoginViewModel : ObservableObject { private readonly IAuthService _authService; private readonly AppSession _session; private readonly INavigationService _navigation; private readonly IConfigService _config; private readonly IAdminAuditService _adminAudit; private readonly IEmployeeLookupService _employeeLookup; private readonly ICanteenBackendApiClient? _backendApi; [ObservableProperty] private string _username = string.Empty; // Updated from code-behind (PasswordBox doesn't support binding cleanly). [ObservableProperty] private string _password = string.Empty; [ObservableProperty] private string _errorMessage = string.Empty; [ObservableProperty] private bool _isBusy; [ObservableProperty] private bool _rememberCredentials; public AdminLoginViewModel( IAuthService authService, AppSession session, INavigationService navigation, IConfigService config, IAdminAuditService adminAudit, IEmployeeLookupService employeeLookup, ICanteenBackendApiClient? backendApi = null) { _authService = authService; _session = session; _navigation = navigation; _config = config; _adminAudit = adminAudit; _employeeLookup = employeeLookup; _backendApi = backendApi; RememberCredentials = _config.GetRememberAdminCredentials(); if (RememberCredentials) { Username = _config.GetSavedAdminUsername(); Password = _config.GetSavedAdminPassword(); } } [RelayCommand] private async Task AdminLoginAsync() { if (IsBusy) return; ErrorMessage = string.Empty; var user = Username?.Trim() ?? string.Empty; var pass = Password ?? string.Empty; // Requirement: always clear fields after clicking LOGIN (success or failure). // Keep local copies for the ongoing request. Username = string.Empty; Password = string.Empty; if (string.IsNullOrWhiteSpace(user) || string.IsNullOrEmpty(pass)) { ErrorMessage = "Username and password are required."; return; } IsBusy = true; try { var result = await _authService.LoginAsync(user, pass).ConfigureAwait(true); if (!result.Success) { ErrorMessage = "Invalid username or password."; FileLogger.Warn("ClientLogin", $"Admin login failed for user '{user}'."); return; } _session.SetAdminAuthenticated(user, result.EmployeeId); await AdminLoginHelper.ApplyAdminLoginDefaultsAsync( result.EmployeeId, _config, _employeeLookup, _backendApi).ConfigureAwait(true); FileLogger.Info( "ClientLogin", $"Admin login succeeded. EmployeeId={result.EmployeeId}, AdminCardId saved, SiteId={_config.GetSiteId()}"); // Persist who logged in (for audit / reporting). await _adminAudit.RecordLoginAsync(user, result.EmployeeId).ConfigureAwait(false); // Persist credentials only if user opted in. _config.SetRememberAdminCredentials(RememberCredentials); if (RememberCredentials) { _config.SetSavedAdminUsername(user); _config.SetSavedAdminPassword(pass); } else { _config.SetSavedAdminUsername(string.Empty); _config.SetSavedAdminPassword(string.Empty); } _navigation.NavigateToScanner(); } finally { IsBusy = false; } } }