@using ShiftScheduler.Shared @using System.Text.Json @inject HttpClient HttpClient @inject IJSRuntime JSRuntime @if (IsVisible) { } @code { [Parameter] public bool IsVisible { get; set; } [Parameter] public EventCallback OnClose { get; set; } [Parameter] public EventCallback OnConfigurationChanged { get; set; } private ApplicationConfiguration _config = new(); private bool _isLoading = false; private bool _isSaving = false; private bool _showImportSection = false; private string _errorMessage = string.Empty; private string _successMessage = string.Empty; private ElementReference _fileInput; protected override async Task OnParametersSetAsync() { if (IsVisible && (_config.Shifts.Count == 0 || _config.Transport.StartStation == string.Empty)) { await LoadConfiguration(); } } private async Task LoadConfiguration() { _isLoading = true; _errorMessage = string.Empty; StateHasChanged(); try { var response = await HttpClient.GetAsync("api/configuration"); if (response.IsSuccessStatusCode) { var json = await response.Content.ReadAsStringAsync(); _config = JsonSerializer.Deserialize(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }) ?? new ApplicationConfiguration(); } else { _errorMessage = "Failed to load configuration"; } } catch (Exception ex) { _errorMessage = $"Error loading configuration: {ex.Message}"; } finally { _isLoading = false; StateHasChanged(); } } private async Task Save() { _isSaving = true; _errorMessage = string.Empty; _successMessage = string.Empty; StateHasChanged(); try { var response = await HttpClient.PutAsJsonAsync("api/configuration", _config); if (response.IsSuccessStatusCode) { _successMessage = "Configuration saved successfully!"; await OnConfigurationChanged.InvokeAsync(); await Task.Delay(1000); // Show success message briefly await Close(); } else { _errorMessage = "Failed to save configuration"; } } catch (Exception ex) { _errorMessage = $"Error saving configuration: {ex.Message}"; } finally { _isSaving = false; StateHasChanged(); } } private async Task ExportConfiguration() { try { var response = await HttpClient.GetAsync("api/configuration/export"); if (response.IsSuccessStatusCode) { var bytes = await response.Content.ReadAsByteArrayAsync(); var base64 = Convert.ToBase64String(bytes); await JSRuntime.InvokeVoidAsync("downloadFile", "ShiftScheduler-Configuration.json", "application/json", base64); } } catch (Exception ex) { _errorMessage = $"Error exporting configuration: {ex.Message}"; StateHasChanged(); } } private async Task ImportConfiguration() { try { var result = await JSRuntime.InvokeAsync("readFileAsText", _fileInput); if (!string.IsNullOrEmpty(result)) { var request = new { JsonContent = result }; var response = await HttpClient.PostAsJsonAsync("api/configuration/import", request); if (response.IsSuccessStatusCode) { await LoadConfiguration(); _successMessage = "Configuration imported successfully!"; _showImportSection = false; } else { _errorMessage = "Failed to import configuration"; } } } catch (Exception ex) { _errorMessage = $"Error importing configuration: {ex.Message}"; } StateHasChanged(); } private void AddShift() { _config.Shifts.Add(new Shift { Name = "New Shift", Icon = "⭐", MorningTime = "", AfternoonTime = "" }); StateHasChanged(); } private void RemoveShift(int index) { if (index >= 0 && index < _config.Shifts.Count) { _config.Shifts.RemoveAt(index); StateHasChanged(); } } private async Task Close() { _errorMessage = string.Empty; _successMessage = string.Empty; _showImportSection = false; await OnClose.InvokeAsync(); } }