Utopia-Canteen-System/ViewModels/SettingsViewModel.cs

188 lines
5.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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 _scanIntervalDays = "0";
[ObservableProperty]
private string _scanIntervalHours = "0";
[ObservableProperty]
private string _scanIntervalMinutes = "1";
[ObservableProperty]
private string _scanIntervalSeconds = "0";
[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 config from service.</summary>
public void LoadFromConfig()
{
SyncApiEndpoint = _configService.GetSyncApiEndpoint();
ScanIntervalDays = _configService.GetScanIntervalDays().ToString();
ScanIntervalHours = _configService.GetScanIntervalHours().ToString();
ScanIntervalMinutes = _configService.GetScanIntervalMinutes().ToString();
ScanIntervalSeconds = _configService.GetScanIntervalSeconds().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(ScanIntervalDays, out var days) || days < 0 || days > 365)
{
SaveMessage = "Scan interval Days must be 0365.";
IsError = true;
IsSaving = false;
return;
}
if (!int.TryParse(ScanIntervalHours, out var hours) || hours < 0 || hours > 23)
{
SaveMessage = "Scan interval Hours must be 023.";
IsError = true;
IsSaving = false;
return;
}
if (!int.TryParse(ScanIntervalMinutes, out var minutes) || minutes < 0 || minutes > 59)
{
SaveMessage = "Scan interval Minutes must be 059.";
IsError = true;
IsSaving = false;
return;
}
if (!int.TryParse(ScanIntervalSeconds, out var seconds) || seconds < 0 || seconds > 59)
{
SaveMessage = "Scan interval Seconds must be 059.";
IsError = true;
IsSaving = false;
return;
}
if (days == 0 && hours == 0 && minutes == 0 && seconds == 0)
{
SaveMessage = "Scan interval cannot be zero. Use at least 1 second.";
IsError = true;
IsSaving = false;
return;
}
_configService.SetSyncApiEndpoint(SyncApiEndpoint?.Trim() ?? string.Empty);
_configService.SetScanIntervalDays(days);
_configService.SetScanIntervalHours(hours);
_configService.SetScanIntervalMinutes(minutes);
_configService.SetScanIntervalSeconds(seconds);
_configService.SetAdminCardId(AdminCardId?.Trim() ?? string.Empty);
SaveMessage = "Settings saved.";
IsError = false;
IsSaving = false;
}
[RelayCommand]
private void Back()
{
_navigation.NavigateBackFromSettings(GetDashboardTimeout());
}
/// <summary>Opens Meal Schedules admin screen (Phase 2.5).</summary>
[RelayCommand]
private void OpenMealSchedules()
{
_navigation.NavigateToMealSchedules();
}
[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() => _configService.GetScanInterval();
}