diff --git a/CulinaryCommandApp/Components/App.razor b/CulinaryCommandApp/Components/App.razor
index 88e8715..ac942af 100644
--- a/CulinaryCommandApp/Components/App.razor
+++ b/CulinaryCommandApp/Components/App.razor
@@ -13,7 +13,8 @@
-
+
+ @* *@
diff --git a/CulinaryCommandApp/Components/Custom/LocationSelector.razor b/CulinaryCommandApp/Components/Custom/LocationSelector.razor
index a3696b2..be2c064 100644
--- a/CulinaryCommandApp/Components/Custom/LocationSelector.razor
+++ b/CulinaryCommandApp/Components/Custom/LocationSelector.razor
@@ -2,6 +2,7 @@
@using CulinaryCommand.Data.Entities
@using System.Text.Json
@using CulinaryCommand.Services.UserContextSpace
+@using System.Numerics
@inject ILocationService LocationService
@inject LocationState LocationState
@@ -59,22 +60,31 @@
@code {
private List ManagedLocations { get; set; } = new();
private bool _loadedOnce;
+
+ protected override void OnInitialized()
+ {
+ LocationState.OnChange += StateHasChanged;
+ }
+
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (!firstRender || _loadedOnce) return;
_loadedOnce = true;
- // 1) Load cached instantly (never fails hard)
+ // 1) Load cached instantly
ManagedLocations = await LoadCachedLocationsAsync();
- if (LocationState.CurrentLocation == null && ManagedLocations.Any())
- await LocationState.SetCurrentLocationAsync(ManagedLocations.First());
+ var savedId = await JS.InvokeAsync("localStorage.getItem", LocationState.ActiveLocStorageKey);
+ var savedLocation = int.TryParse(savedId, out var id)
+ ? ManagedLocations.FirstOrDefault(l => l.Id == id)
+ : null;
+
+ await LocationState.SetCurrentLocationAsync(savedLocation);
StateHasChanged();
- // 2) Load fresh server data if we can resolve user context
+ // 2) Load fresh server data after
await LoadLocationsFromServerAsync();
-
StateHasChanged();
}
@@ -83,6 +93,7 @@
try
{
var json = await JS.InvokeAsync("localStorage.getItem", "cc_locations");
+
return string.IsNullOrWhiteSpace(json)
? new List()
: (JsonSerializer.Deserialize>(json) ?? new List());
@@ -139,4 +150,9 @@
{
NavigationManager.NavigateTo($"/settings/locations/{location.Id}");
}
+
+ public void Dispose()
+ {
+ LocationState.OnChange -= StateHasChanged;
+ }
}
diff --git a/CulinaryCommandApp/Components/Custom/LogoutWidget.razor b/CulinaryCommandApp/Components/Custom/LogoutWidget.razor
index 6b9a55c..72ad2e5 100644
--- a/CulinaryCommandApp/Components/Custom/LogoutWidget.razor
+++ b/CulinaryCommandApp/Components/Custom/LogoutWidget.razor
@@ -1,11 +1,19 @@
@rendermode InteractiveServer
@inject NavigationManager Nav
+@inject IJSRuntime JS
+@inject LocationState LocationState
+
+
@code {
private async Task Logout()
{
+ await JS.InvokeVoidAsync("localStorage.clear");
+ await JS.InvokeVoidAsync("sessionStorage.clear");
+ LocationState.FlushLocationState();
+
Nav.NavigateTo("/signin", true); // hard reload
}
}
diff --git a/CulinaryCommandApp/Components/Custom/ProfileDropdown.razor b/CulinaryCommandApp/Components/Custom/ProfileDropdown.razor
index e4aba68..e7de7df 100644
--- a/CulinaryCommandApp/Components/Custom/ProfileDropdown.razor
+++ b/CulinaryCommandApp/Components/Custom/ProfileDropdown.razor
@@ -1,6 +1,9 @@
@using CulinaryCommand.Services
@using CulinaryCommand.Services.UserContextSpace
@inject IUserContextService UserCtx
+@inject IJSRuntime JS
+@inject LocationState LocationState
+
@inject NavigationManager Nav
@rendermode InteractiveServer
@@ -64,8 +67,14 @@
StateHasChanged();
}
+ private async Task Logout()
+ {
+ await JS.InvokeVoidAsync("localStorage.clear");
+ await JS.InvokeVoidAsync("sessionStorage.clear");
+ LocationState.FlushLocationState();
- private void Logout() => Nav.NavigateTo("/logout", forceLoad: true);
+ Nav.NavigateTo("/logout", forceLoad: true);
+ }
diff --git a/CulinaryCommandApp/Services/LocationService.cs b/CulinaryCommandApp/Services/LocationService.cs
index d81e2b9..db261b8 100644
--- a/CulinaryCommandApp/Services/LocationService.cs
+++ b/CulinaryCommandApp/Services/LocationService.cs
@@ -255,7 +255,7 @@ public async Task LoadAndPersistLocationsAsync(int userId)
if (_locationState.CurrentLocation != null)
{
await _js.InvokeVoidAsync("localStorage.setItem",
- "cc_activeLocationId",
+ LocationState.ActiveLocStorageKey,
_locationState.CurrentLocation.Id);
}
}
diff --git a/CulinaryCommandApp/Services/LocationState.cs b/CulinaryCommandApp/Services/LocationState.cs
index 06cfaaf..70fd656 100644
--- a/CulinaryCommandApp/Services/LocationState.cs
+++ b/CulinaryCommandApp/Services/LocationState.cs
@@ -6,6 +6,7 @@ namespace CulinaryCommand.Services
{
public class LocationState
{
+ public const string ActiveLocStorageKey = "cc_activeLocationId";
private readonly IJSRuntime _js;
public List ManagedLocations { get; private set; } = new();
public Location? CurrentLocation { get; private set; }
@@ -23,7 +24,7 @@ public async Task HydrateAsync()
{
if (CurrentLocation != null) return; // Already have it
- var savedId = await _js.InvokeAsync("localStorage.getItem", "cc_selected_location_id");
+ var savedId = await _js.InvokeAsync("localStorage.getItem", ActiveLocStorageKey);
if (!string.IsNullOrEmpty(savedId) && int.TryParse(savedId, out int id))
{
@@ -40,7 +41,7 @@ public async Task SetLocationsAsync(List? locations)
string? savedId = null;
try
{
- savedId = await _js.InvokeAsync("localStorage.getItem", "cc_activeLocationId");
+ savedId = await _js.InvokeAsync("localStorage.getItem", ActiveLocStorageKey);
}
catch (InvalidOperationException)
{
@@ -65,9 +66,9 @@ public async Task SetCurrentLocationAsync(Location? loc)
try
{
if (loc is null)
- await _js.InvokeVoidAsync("localStorage.removeItem", "cc_activeLocationId");
+ await _js.InvokeVoidAsync("localStorage.removeItem", ActiveLocStorageKey);
else
- await _js.InvokeVoidAsync("localStorage.setItem", "cc_activeLocationId", loc.Id.ToString());
+ await _js.InvokeVoidAsync("localStorage.setItem", ActiveLocStorageKey, loc.Id.ToString());
}
catch (InvalidOperationException)
{
@@ -77,5 +78,11 @@ public async Task SetCurrentLocationAsync(Location? loc)
// OnChange?.Invoke();
NotifyStateChanged();
}
+
+ public void FlushLocationState()
+ {
+ ManagedLocations = new List();
+ CurrentLocation = null;
+ }
}
}
diff --git a/CulinaryCommandApp/wwwroot/images/cc_favicon_black2.png b/CulinaryCommandApp/wwwroot/images/cc_favicon_black2.png
new file mode 100644
index 0000000..9ac1dcb
Binary files /dev/null and b/CulinaryCommandApp/wwwroot/images/cc_favicon_black2.png differ
diff --git a/CulinaryCommandApp/wwwroot/images/cc_favicon_green_clear2.png b/CulinaryCommandApp/wwwroot/images/cc_favicon_green_clear2.png
new file mode 100644
index 0000000..6dfaddc
Binary files /dev/null and b/CulinaryCommandApp/wwwroot/images/cc_favicon_green_clear2.png differ
diff --git a/CulinaryCommandApp/wwwroot/images/favicon.png b/CulinaryCommandApp/wwwroot/images/favicon-old.png
similarity index 100%
rename from CulinaryCommandApp/wwwroot/images/favicon.png
rename to CulinaryCommandApp/wwwroot/images/favicon-old.png
diff --git a/CulinaryCommandApp/wwwroot/images/favicon.ico b/CulinaryCommandApp/wwwroot/images/favicon.ico
new file mode 100644
index 0000000..4305ade
Binary files /dev/null and b/CulinaryCommandApp/wwwroot/images/favicon.ico differ