From c7221ea02125a5d82c837fb55e31dfeb5c40b3c6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 17 Aug 2025 19:17:04 +0000 Subject: [PATCH] Implement localStorage persistence for shift selections Co-authored-by: clayschaad <11883505+clayschaad@users.noreply.github.com> --- Client/Pages/Index.razor.cs | 62 +++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/Client/Pages/Index.razor.cs b/Client/Pages/Index.razor.cs index 582534b..c3c113d 100644 --- a/Client/Pages/Index.razor.cs +++ b/Client/Pages/Index.razor.cs @@ -1,26 +1,37 @@ using Microsoft.AspNetCore.Components; +using Microsoft.JSInterop; using ShiftScheduler.Shared.Models; using System.Net.Http.Json; +using System.Text.Json; namespace ShiftScheduler.Client.Pages { public partial class Index : ComponentBase { [Inject] private HttpClient HttpClient { get; set; } = default!; + [Inject] private IJSRuntime JSRuntime { get; set; } = default!; + [Inject] private NavigationManager NavigationManager { get; set; } = default!; private List DaysInMonth { get; set; } = new(); private List Shifts { get; set; } = new(); private Dictionary SelectedSchedule { get; set; } = new(); + private int CurrentMonth { get; set; } + private int CurrentYear { get; set; } protected override async Task OnInitializedAsync() { var (nextMonth, year) = GetNextMonthAndYear(); + CurrentMonth = nextMonth; + CurrentYear = year; DaysInMonth = Enumerable.Range(1, DateTime.DaysInMonth(year, nextMonth)) .Select(d => new DateTime(year, nextMonth, d)) .ToList(); Shifts = await HttpClient.GetFromJsonAsync>("api/shift/shifts") ?? new(); + + // Load saved schedule for this month + await LoadScheduleFromStorage(); } private (int nextMonth, int year) GetNextMonthAndYear() @@ -31,9 +42,10 @@ namespace ShiftScheduler.Client.Pages return (nextMonth, year); } - private void SelectShift(DateTime day, string shiftName) + private async void SelectShift(DateTime day, string shiftName) { SelectedSchedule[day] = shiftName; + await SaveScheduleToStorage(); } private async Task ExportToIcs() @@ -54,6 +66,52 @@ namespace ShiftScheduler.Client.Pages NavigationManager.NavigateTo(fileUrl, true); } - [Inject] private NavigationManager NavigationManager { get; set; } = default!; + private async Task SaveScheduleToStorage() + { + try + { + var storageKey = $"ShiftSchedule_{CurrentYear}_{CurrentMonth:D2}"; + + // Convert DateTime keys to string for JSON serialization + var serializableSchedule = SelectedSchedule.ToDictionary( + kvp => kvp.Key.ToString("yyyy-MM-dd"), + kvp => kvp.Value + ); + + var json = JsonSerializer.Serialize(serializableSchedule); + await JSRuntime.InvokeVoidAsync("localStorage.setItem", storageKey, json); + } + catch (Exception) + { + // Silently fail if localStorage is not available + } + } + + private async Task LoadScheduleFromStorage() + { + try + { + var storageKey = $"ShiftSchedule_{CurrentYear}_{CurrentMonth:D2}"; + var json = await JSRuntime.InvokeAsync("localStorage.getItem", storageKey); + + if (!string.IsNullOrEmpty(json)) + { + var serializableSchedule = JsonSerializer.Deserialize>(json); + if (serializableSchedule != null) + { + // Convert string keys back to DateTime + SelectedSchedule = serializableSchedule.ToDictionary( + kvp => DateTime.Parse(kvp.Key), + kvp => kvp.Value + ); + } + } + } + catch (Exception) + { + // Silently fail if localStorage is not available or data is corrupted + SelectedSchedule = new Dictionary(); + } + } } }