using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using UtopiaCanteenSystem.Services; namespace UtopiaCanteenSystem.ViewModels; /// /// ViewModel for SettingsView: editable API endpoint (UIND sync URL), save, load from config. /// 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(); } /// Loads SyncApiEndpoint from config service. 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); } }