Styles & Home Page Content Cleanup

Mobile Menu System & Dark Mode Cookie
Theme Draft
This commit is contained in:
daniel-c-harvey
2025-12-09 16:46:07 -05:00
parent bb3551a248
commit bc521d5b29
26 changed files with 461 additions and 168 deletions
@@ -0,0 +1,118 @@
@using DeepDrftWeb.Client.Controls
@using DeepDrftWeb.Client.Services
<MudAppBar Elevation="@Elevation">
<div class="d-inline-flex align-center flex-1 justify-space-between">
@if (_isDesktop)
{
<div>
<MudStack Row AlignItems="AlignItems.Center" Spacing="6">
<MudLink Href="/" Underline="Underline.None">
<MudStack Row AlignItems="AlignItems.Center">
<MudAvatar Class="mr-2">
<MudImage Src="img/deepdrft-logo.jpg"></MudImage>
</MudAvatar>
<div>Deep DRFT</div>
</MudStack>
</MudLink>
</MudStack>
</div>
<div>
<MudStack Spacing="8" Row AlignItems="AlignItems.Center">
@foreach (PageRoute thePage in Pages.AllPages)
{
<AppNavLink Href="@thePage.Route" Icon="@thePage.Icon">@thePage.Name</AppNavLink>
}
</MudStack>
</div>
}
else
{
<div>
<MudStack Row AlignItems="AlignItems.Center">
<MudMenu RelativeWidth="DropdownWidth.Adaptive">
<ActivatorContent>
<MudStack Row AlignItems="AlignItems.Center" Spacing="4">
<MudIcon Icon="@Icons.Material.Filled.Menu"/>
<MudAvatar Class="mr-2">
<MudImage Src="img/deepdrft-logo.jpg"></MudImage>
</MudAvatar>
<div>Deep DRFT</div>
</MudStack>
</ActivatorContent>
<ChildContent>
@foreach (PageRoute route in Pages.AllPages)
{
<MudMenuItem Href="@route.Route" Class="px-6">
<MudStack Row AlignItems="AlignItems.Center">
<MudIcon Icon="@route.Icon" Color="Color.Primary"/>
<MudText Typo="Typo.button" Color="Color.Primary">
@route.Name
</MudText>
</MudStack>
</MudMenuItem>
}
</ChildContent>
</MudMenu>
</MudStack>
</div>
}
<div>
<MudIconButton Icon="@(DarkLightModeButtonIcon)" Color="Color.Inherit" OnClick="@DarkModeToggle"/>
</div>
</div>
</MudAppBar>
@code {
[Inject] public required IBrowserViewportService BrowserViewportService { get; set; }
[Inject] public required DarkModeCookieService DarkModeCookieService { get; set; }
[Parameter] public int Elevation { get; set; }
[Parameter] public required bool IsDarkMode { get; set; }
[Parameter] public required EventCallback<bool> IsDarkModeChanged { get; set; }
private bool _isDesktop = true;
private Guid _viewportSubscriptionId;
protected override async Task OnInitializedAsync()
{
IsDarkMode = DarkModeCookieService.GetDarkModeAsync();
await IsDarkModeChanged.InvokeAsync(IsDarkMode);
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
var breakpoint = await BrowserViewportService.GetCurrentBreakpointAsync();
_isDesktop = breakpoint >= Breakpoint.Sm;
_viewportSubscriptionId = Guid.NewGuid();
await BrowserViewportService.SubscribeAsync(
_viewportSubscriptionId,
args =>
{
_isDesktop = args.Breakpoint >= Breakpoint.Sm;
InvokeAsync(StateHasChanged);
},
new ResizeOptions { NotifyOnBreakpointOnly = true },
fireImmediately: true);
StateHasChanged();
}
}
private string DarkLightModeButtonIcon => IsDarkMode switch
{
true => DDIcons.GasLampLit,
false => DDIcons.GasLamp,
};
private async Task DarkModeToggle()
{
IsDarkMode = !IsDarkMode;
await DarkModeCookieService.SetDarkModeAsync(IsDarkMode);
await IsDarkModeChanged.InvokeAsync(IsDarkMode);
}
}
+55 -44
View File
@@ -1,6 +1,10 @@
@using DeepDrftWeb.Client.Controls
@using DeepDrftWeb.Client.Controls.AudioPlayerBar
@using DeepDrftWeb.Client.Services
@using DeepDrftWeb.Client.Common
@using Microsoft.AspNetCore.Components
@inherits LayoutComponentBase
@implements IDisposable
<MudThemeProvider Theme="@_themeManager.Theme" IsDarkMode="_isDarkMode" />
<MudPopoverProvider />
@@ -9,14 +13,7 @@
<div class="@ThemeWrapperClass">
<MudLayout Style="display: flex; flex-direction: column; min-height: 100vh">
<AudioPlayerProvider>
<MudAppBar Elevation="_themeManager.AppBarElevation">
<MudAvatar Class="mr-2">
<MudImage Src="img/deepdrft-logo.jpg"></MudImage>
</MudAvatar>
<NavMenu />
<MudSpacer/>
<MudIconButton Icon="@(DarkLightModeButtonIcon)" Color="Color.Inherit" OnClick="@DarkModeToggle"/>
</MudAppBar>
<DeepDrftMenu Elevation="_themeManager.AppBarElevation" @bind-IsDarkMode="_isDarkMode" />
<MudMainContent Class="flex-grow-1 pt-16 pb-8">
<MudContainer MaxWidth="MaxWidth.False" Class="pa-4">
@Body
@@ -35,12 +32,31 @@
</div>
@code {
private bool _drawerOpen = true;
private const string DarkModeKey = "darkMode";
private bool _isDarkMode = true;
private PersistingComponentStateSubscription _persistingSubscription;
[Inject] public required PersistentComponentState PersistentState { get; set; }
[Inject] public required DarkModeSettings DarkModeSettings { get; set; }
protected override void OnInitialized()
{
base.OnInitialized();
// Restore persisted dark mode state (from server prerender)
if (PersistentState.TryTakeFromJson<bool>(DarkModeKey, out var restored))
{
_isDarkMode = restored;
DarkModeSettings.IsDarkMode = restored;
}
else
{
_isDarkMode = DarkModeSettings.IsDarkMode;
}
// Register to persist state when prerendering completes
_persistingSubscription = PersistentState.RegisterOnPersisting(PersistDarkMode);
_themeManager = new ThemeManagerTheme
{
Theme =
@@ -59,23 +75,23 @@
},
H2 = new H2Typography()
{
FontFamily = new[] {"EB Garamond", "serif"}
FontFamily = new[] {"Cormorant", "serif"}
},
H3 = new H3Typography()
{
FontFamily = new[] {"EB Garamond", "serif"}
FontFamily = new[] {"Cormorant", "serif"}
},
H4 = new H4Typography()
{
FontFamily = new[] {"EB Garamond", "serif"}
FontFamily = new[] {"Cormorant", "serif"}
},
H5 = new H5Typography()
{
FontFamily = new[] {"EB Garamond", "serif"}
FontFamily = new[] {"Cormorant", "serif"}
},
H6 = new H6Typography()
{
FontFamily = new[] {"EB Garamond", "serif"}
FontFamily = new[] {"Cormorant", "serif"}
},
Button = new ButtonTypography()
{
@@ -87,16 +103,6 @@
StateHasChanged();
}
private void DrawerToggle()
{
_drawerOpen = !_drawerOpen;
}
private void DarkModeToggle()
{
_isDarkMode = !_isDarkMode;
}
private ThemeManagerTheme _themeManager;
public bool _themeManagerOpen = false;
@@ -113,31 +119,31 @@
}
// Charleston in the Day - Light Theme
// Inspired by Charleston's historic architecture: white stucco, black wrought iron gates, elegant accents
// Inspired by Charleston's historic architecture: wrought iron, bronze, Atlantic coast
private readonly PaletteLight _lightPalette = new()
{
Primary = "#1C1C1C", // Wrought iron black - strong, elegant
Secondary = "#B8848C", // Dusty rose - elegant accent
Tertiary = "#C9A962", // Antique gold - replaces brown
Primary = "#1A1A1A", // Wrought iron black
Secondary = "#B8623D", // Burnished copper - warm orange bronze
Tertiary = "#2A7B8C", // Atlantic turquoise
Info = "#2196F3", // MudBlazor default blue (semantic)
Success = "#4CAF50", // MudBlazor default green (semantic)
Warning = "#FF9800", // MudBlazor default amber (semantic)
Error = "#F44336", // MudBlazor default red (semantic)
Black = "#1C1C1C", // Wrought iron black
Black = "#1A1A1A", // Wrought iron black
White = "#FDFBF7", // Cream white (stucco)
Surface = "#FDFBF7", // Cream stucco surface
Background = "#F5F2EC", // Warm linen background
AppbarText = "#FDFBF7", // Cream text on dark appbar (FIX)
AppbarBackground = "#1C1C1C", // Solid wrought iron appbar
AppbarText = "#FDFBF7", // Cream text on dark appbar
AppbarBackground = "#1A1A1A", // Solid wrought iron appbar
DrawerBackground = "#F5F2EC", // Linen drawer
TextPrimary = "#1C1C1C", // Wrought iron text
TextPrimary = "#1A1A1A", // Wrought iron text
TextSecondary = "#4A4A4A", // Softer iron text
GrayLight = "rgba(28,28,28,0.08)", // Light iron tint
GrayLighter = "rgba(28,28,28,0.04)", // Very light iron tint
GrayDefault = "rgba(28,28,28,0.15)", // Medium iron tint
GrayDark = "rgba(28,28,28,0.25)", // Darker iron tint
Divider = "rgba(28,28,28,0.12)", // Subtle divider lines
TableLines = "rgba(28,28,28,0.12)", // Table borders
GrayLight = "rgba(26,26,26,0.08)", // Light iron tint
GrayLighter = "rgba(26,26,26,0.04)", // Very light iron tint
GrayDefault = "rgba(26,26,26,0.15)", // Medium iron tint
GrayDark = "rgba(26,26,26,0.25)", // Darker iron tint
Divider = "rgba(26,26,26,0.12)", // Subtle divider lines
TableLines = "rgba(26,26,26,0.12)", // Table borders
};
// Lowcountry Summer Nights - Dark Theme
@@ -178,14 +184,19 @@
OverlayDark = "rgba(255,255,255,0.08)", // Light overlay
};
public string DarkLightModeButtonIcon => _isDarkMode switch
{
true => Icons.Material.Rounded.AutoMode,
false => Icons.Material.Outlined.DarkMode,
};
// Theme wrapper class for CSS targeting
private string ThemeWrapperClass => _isDarkMode ? "deepdrft-theme-dark" : "deepdrft-theme-light";
private Task PersistDarkMode()
{
PersistentState.PersistAsJson(DarkModeKey, _isDarkMode);
return Task.CompletedTask;
}
public void Dispose()
{
_persistingSubscription.Dispose();
}
}
-2
View File
@@ -1,7 +1,5 @@
@using DeepDrftWeb.Client.Controls
<AppNavLink Href="" Match="NavLinkMatch.All" Icon="@Icons.Material.Filled.Home">Home</AppNavLink>
<AppNavLink Href="/tracks" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.LibraryMusic">Track Gallery</AppNavLink>
+24
View File
@@ -0,0 +1,24 @@
using MudBlazor;
namespace DeepDrftWeb.Client.Layout;
public class PageRoute
{
public string Name { get; set; } = string.Empty;
public string Route { get; set; } = string.Empty;
public string? Icon { get; set; } = null;
}
public static class Pages
{
public static readonly List<PageRoute> MenuPages =
[
new() { Name = "Track Gallery", Route = "/tracks", Icon = Icons.Material.Filled.LibraryMusic }
];
public static readonly List<PageRoute> AllPages =
new List<PageRoute>
{
new() { Name = "Home", Route = "/", Icon = Icons.Material.Filled.Home }
}.Concat(MenuPages).ToList();
}