From b6b31dc9373dab3a0263666f5c2856d4dcfbcf1d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 20 Aug 2025 06:19:20 +0000 Subject: [PATCH] Complete UI improvements: add month to title, remove sidebar, move buttons to top, show shift times, add loading spinner Co-authored-by: clayschaad <11883505+clayschaad@users.noreply.github.com> --- Client/Pages/Index.razor | 33 ++++++++++----- Client/Pages/Index.razor.cs | 27 ++++++++++++ Client/Pages/Index.razor.css | 50 ++++++++++++++++++++++ Client/Shared/MainLayout.razor | 4 -- Client/Shared/MainLayout.razor.css | 13 +----- Client/Shared/NavMenu.razor | 29 ------------- Client/Shared/NavMenu.razor.css | 68 ------------------------------ 7 files changed, 101 insertions(+), 123 deletions(-) delete mode 100644 Client/Shared/NavMenu.razor delete mode 100644 Client/Shared/NavMenu.razor.css diff --git a/Client/Pages/Index.razor b/Client/Pages/Index.razor index b444288..96ea71f 100644 --- a/Client/Pages/Index.razor +++ b/Client/Pages/Index.razor @@ -1,6 +1,24 @@ @page "/" -

Shift Scheduler

+
+ + + +
+ +

Shift Scheduler - @CurrentMonthYear

+ +@if (_isLoadingInitial) +{ +
+
+
⏳
+

Loading shifts and transport data...

+
+
+} +else +{
@foreach (var day in DaysInMonth) @@ -31,6 +49,9 @@
@if (SelectedSchedule.ContainsKey(day)) { +
+ @GetShiftTimes(day) +
@GetTransportSummary(day)
@@ -38,12 +59,4 @@ } - -
- -
- -
- - -
+} diff --git a/Client/Pages/Index.razor.cs b/Client/Pages/Index.razor.cs index 8b95a79..e9841b8 100644 --- a/Client/Pages/Index.razor.cs +++ b/Client/Pages/Index.razor.cs @@ -19,9 +19,14 @@ namespace ShiftScheduler.Client.Pages private int EditMonth { get; set; } private int EditYear { get; set; } private bool _isLoadingTransport = false; + private bool _isLoadingInitial = false; + + private string CurrentMonthYear => new DateTime(EditYear, EditMonth, 1).ToString("MMMM yyyy"); protected override async Task OnInitializedAsync() { + _isLoadingInitial = true; + (EditMonth, EditYear) = GetNextMonthAndYear(); DaysInMonth = Enumerable.Range(1, DateTime.DaysInMonth(EditYear, EditMonth)) @@ -31,6 +36,9 @@ namespace ShiftScheduler.Client.Pages Shifts = await HttpClient.GetFromJsonAsync>("api/shift/shifts") ?? new(); await LoadScheduleFromStorage(); + + _isLoadingInitial = false; + StateHasChanged(); } private (int nextMonth, int year) GetNextMonthAndYear() @@ -231,5 +239,24 @@ namespace ShiftScheduler.Client.Pages return string.Join(" | ", summaries); } + + // Helper method to get shift times for display + public string GetShiftTimes(DateTime date) + { + if (!SelectedSchedule.TryGetValue(date, out var shiftName)) + return string.Empty; + + var shift = Shifts.FirstOrDefault(s => s.Name == shiftName); + if (shift == null) + return string.Empty; + + var times = new List(); + if (!string.IsNullOrEmpty(shift.MorningTime)) + times.Add(shift.MorningTime); + if (!string.IsNullOrEmpty(shift.AfternoonTime)) + times.Add(shift.AfternoonTime); + + return string.Join(" | ", times); + } } } diff --git a/Client/Pages/Index.razor.css b/Client/Pages/Index.razor.css index 1a04a16..40fe2b8 100644 --- a/Client/Pages/Index.razor.css +++ b/Client/Pages/Index.razor.css @@ -1,3 +1,41 @@ +/* Header buttons */ +.header-buttons { + display: flex; + justify-content: flex-end; + gap: 10px; + margin-bottom: 20px; + padding: 10px 0; + border-bottom: 1px solid #ddd; +} + +/* Loading overlay */ +.loading-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(255, 255, 255, 0.8); + display: flex; + justify-content: center; + align-items: center; + z-index: 1000; +} + +.loading-content { + text-align: center; + background-color: white; + padding: 20px; + border-radius: 8px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); +} + +.loading-content .loading-spinner { + font-size: 2rem; + animation: spin 1s linear infinite; + margin-bottom: 10px; +} + /* Calendar container */ .calendar-grid { display: grid; @@ -154,6 +192,18 @@ min-height: 20px; } +/* Shift times styling */ +.shift-times { + margin-top: 8px; + padding: 4px; + background-color: #f0f8e0; + border-radius: 4px; + font-size: 0.75rem; + color: #2d5016; + word-wrap: break-word; + font-weight: bold; +} + /* Loading spinner */ .loading-spinner { animation: spin 1s linear infinite; diff --git a/Client/Shared/MainLayout.razor b/Client/Shared/MainLayout.razor index 839b8fe..d8f57dc 100644 --- a/Client/Shared/MainLayout.razor +++ b/Client/Shared/MainLayout.razor @@ -1,10 +1,6 @@ @inherits LayoutComponentBase
- -
About diff --git a/Client/Shared/MainLayout.razor.css b/Client/Shared/MainLayout.razor.css index c865427..29d2e77 100644 --- a/Client/Shared/MainLayout.razor.css +++ b/Client/Shared/MainLayout.razor.css @@ -8,10 +8,6 @@ main { flex: 1; } -.sidebar { - background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%); -} - .top-row { background-color: #f7f7f7; border-bottom: 1px solid #d6d5d5; @@ -52,14 +48,7 @@ main { @media (min-width: 641px) { .page { - flex-direction: row; - } - - .sidebar { - width: 250px; - height: 100vh; - position: sticky; - top: 0; + flex-direction: column; } .top-row { diff --git a/Client/Shared/NavMenu.razor b/Client/Shared/NavMenu.razor deleted file mode 100644 index 00edf23..0000000 --- a/Client/Shared/NavMenu.razor +++ /dev/null @@ -1,29 +0,0 @@ - - - - -@code { - private bool collapseNavMenu = true; - - private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null; - - private void ToggleNavMenu() - { - collapseNavMenu = !collapseNavMenu; - } -} diff --git a/Client/Shared/NavMenu.razor.css b/Client/Shared/NavMenu.razor.css deleted file mode 100644 index 604b7a1..0000000 --- a/Client/Shared/NavMenu.razor.css +++ /dev/null @@ -1,68 +0,0 @@ -.navbar-toggler { - background-color: rgba(255, 255, 255, 0.1); -} - -.top-row { - height: 3.5rem; - background-color: rgba(0,0,0,0.4); -} - -.navbar-brand { - font-size: 1.1rem; -} - -.oi { - width: 2rem; - font-size: 1.1rem; - vertical-align: text-top; - top: -2px; -} - -.nav-item { - font-size: 0.9rem; - padding-bottom: 0.5rem; -} - - .nav-item:first-of-type { - padding-top: 1rem; - } - - .nav-item:last-of-type { - padding-bottom: 1rem; - } - - .nav-item ::deep a { - color: #d7d7d7; - border-radius: 4px; - height: 3rem; - display: flex; - align-items: center; - line-height: 3rem; - } - -.nav-item ::deep a.active { - background-color: rgba(255,255,255,0.25); - color: white; -} - -.nav-item ::deep a:hover { - background-color: rgba(255,255,255,0.1); - color: white; -} - -@media (min-width: 641px) { - .navbar-toggler { - display: none; - } - - .collapse { - /* Never collapse the sidebar for wide screens */ - display: block; - } - - .nav-scrollable { - /* Allow sidebar to scroll for tall menus */ - height: calc(100vh - 3.5rem); - overflow-y: auto; - } -}