diff --git a/.gitignore b/.gitignore index 7292033..95fa510 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,10 @@ # Build outputs bin/ obj/ +node_modules/ +test-results/ +playwright-report/ +blob-report/ # User-specific files *.user @@ -27,6 +31,8 @@ Data/*.db-* *.sqlite3 App_Data/ .docker-data/ +probe-desktop.png +probe-mobile.png # Secrets and environment files .env diff --git a/Components/App.razor b/Components/App.razor index a2917af..1cf0d7a 100644 --- a/Components/App.razor +++ b/Components/App.razor @@ -5,6 +5,28 @@ + @@ -15,6 +37,7 @@ + diff --git a/Components/Layout/MainLayout.razor b/Components/Layout/MainLayout.razor index 7e9232b..b49bc25 100644 --- a/Components/Layout/MainLayout.razor +++ b/Components/Layout/MainLayout.razor @@ -1,24 +1,16 @@ @inherits LayoutComponentBase +@implements IDisposable + +@inject AppThemeState ThemeState +@inject IJSRuntime JS
- About
@@ -37,8 +29,39 @@ @code { private bool sidebarCollapsed = true; + protected override void OnInitialized() + { + ThemeState.ThemeModeChanged += HandleThemeModeChanged; + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (!firstRender) + { + return; + } + + var themeMode = await ThemeState.EnsureLoadedAsync(); + await ApplyThemeAsync(themeMode); + } + private void ToggleSidebar() { sidebarCollapsed = !sidebarCollapsed; } + + private void HandleThemeModeChanged(AppThemeMode themeMode) + { + _ = InvokeAsync(() => ApplyThemeAsync(themeMode).AsTask()); + } + + private ValueTask ApplyThemeAsync(AppThemeMode themeMode) + { + return JS.InvokeVoidAsync("workTrackerTheme.setTheme", themeMode.ToString().ToLowerInvariant()); + } + + public void Dispose() + { + ThemeState.ThemeModeChanged -= HandleThemeModeChanged; + } } diff --git a/Components/Layout/MainLayout.razor.css b/Components/Layout/MainLayout.razor.css index 8204d7a..cfbb458 100644 --- a/Components/Layout/MainLayout.razor.css +++ b/Components/Layout/MainLayout.razor.css @@ -14,8 +14,8 @@ main { } .top-row { - background-color: #f7f7f7; - border-bottom: 1px solid #d6d5d5; + background-color: var(--wt-header-bg); + border-bottom: 1px solid var(--wt-header-border); justify-content: flex-end; height: 3.5rem; display: flex; @@ -23,6 +23,7 @@ main { } .top-row ::deep a, .top-row ::deep .btn-link { + color: var(--wt-header-link); white-space: nowrap; margin-left: 1.5rem; text-decoration: none; @@ -37,30 +38,9 @@ main { text-overflow: ellipsis; } -.sidebar-toggle { - display: none; - align-items: center; - justify-content: center; - flex-direction: column; - gap: 0.2rem; - width: 2.5rem; - height: 2.5rem; - margin-right: auto; - border: 1px solid #d6d5d5; - border-radius: 0.65rem; - background: #fff; -} - -.sidebar-toggle-bar { - width: 1rem; - height: 2px; - background: #334155; - border-radius: 999px; -} - @media (max-width: 640.98px) { .top-row { - justify-content: space-between; + justify-content: flex-end; } .top-row ::deep a, .top-row ::deep .btn-link { @@ -100,10 +80,6 @@ main { padding-right: 1.5rem !important; } - .sidebar-toggle { - display: inline-flex; - } - .sidebar.sidebar-collapsed { width: 5rem; } diff --git a/Components/Layout/NavMenu.razor b/Components/Layout/NavMenu.razor index 4a34d50..514e372 100644 --- a/Components/Layout/NavMenu.razor +++ b/Components/Layout/NavMenu.razor @@ -4,15 +4,29 @@ @code { [Parameter] public bool IsCollapsed { get; set; } + [Parameter] public EventCallback OnToggleSidebar { get; set; } + + private Task ToggleSidebarAsync() + { + return OnToggleSidebar.InvokeAsync(); + } }