Utopia-Canteen-System/ViewModels/SettingsViewModel.cs

144 lines
4.0 KiB
C#

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using UtopiaCanteenSystem.Services;
namespace UtopiaCanteenSystem.ViewModels;
/// <summary>
/// ViewModel for SettingsView: editable API endpoint (UIND sync URL), save, load from config.
/// </summary>
public partial class SettingsViewModel : ObservableObject
{
private readonly IConfigService _configService;
private readonly INavigationService _navigation;
private readonly IAdminAuditService _adminAudit;
private readonly ISyncService _syncService;
[ObservableProperty]
private string _syncApiEndpoint = string.Empty;
[ObservableProperty]
private string _scanTimeoutSeconds = "30";
[ObservableProperty]
private string _adminCardId = "ADMIN";
[ObservableProperty]
private string _saveMessage = string.Empty;
[ObservableProperty]
private bool _isError;
[ObservableProperty]
private bool _isSaving;
[ObservableProperty]
private bool _isPosting;
public bool CanPostNow => !IsPosting;
public string PostButtonText => IsPosting ? "Posting..." : "Post Data";
partial void OnIsPostingChanged(bool value)
{
OnPropertyChanged(nameof(PostButtonText));
OnPropertyChanged(nameof(CanPostNow));
}
public SettingsViewModel(
IConfigService configService,
INavigationService navigation,
IAdminAuditService adminAudit,
ISyncService syncService)
{
_configService = configService;
_navigation = navigation;
_adminAudit = adminAudit;
_syncService = syncService;
LoadFromConfig();
}
/// <summary>Loads SyncApiEndpoint from config service.</summary>
public void LoadFromConfig()
{
SyncApiEndpoint = _configService.GetSyncApiEndpoint();
ScanTimeoutSeconds = _configService.GetScanTimeoutSeconds().ToString();
// Always prefer the latest admin login from the database.
var last = _adminAudit.GetLastLogin();
if (last != null && !string.IsNullOrWhiteSpace(last.EmployeeId))
AdminCardId = last.EmployeeId;
else
AdminCardId = "ADMIN";
}
[RelayCommand]
private void Save()
{
IsSaving = true;
if (!int.TryParse(ScanTimeoutSeconds, out var seconds) || seconds <= 0)
{
SaveMessage = "Scan timeout must be a positive number of seconds.";
IsError = true;
IsSaving = false;
return;
}
_configService.SetSyncApiEndpoint(SyncApiEndpoint?.Trim() ?? string.Empty);
_configService.SetScanTimeoutSeconds(seconds);
_configService.SetAdminCardId(AdminCardId?.Trim() ?? string.Empty);
SaveMessage = "Settings saved.";
IsError = false;
IsSaving = false;
}
[RelayCommand]
private void Back()
{
_navigation.NavigateBackFromSettings(GetDashboardTimeout());
}
[RelayCommand]
private async Task PostDataNow()
{
if (IsPosting)
return;
SaveMessage = string.Empty;
IsError = false;
IsPosting = true;
try
{
// If not configured, do not attempt sync.
if (string.IsNullOrWhiteSpace(_configService.GetMySqlConnectionString()))
{
SaveMessage = "MySQL connection string not configured.";
IsError = true;
return;
}
await _syncService.SyncNowAsync().ConfigureAwait(false);
SaveMessage = "Posted data to production.";
IsError = false;
}
catch
{
SaveMessage = "Failed to post data to production.";
IsError = true;
}
finally
{
IsPosting = false;
}
}
private TimeSpan GetDashboardTimeout()
{
var seconds = _configService.GetScanTimeoutSeconds();
if (seconds <= 0)
seconds = 60;
return TimeSpan.FromSeconds(seconds);
}
}