Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CulinaryCommandApp/Components/App.razor
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
<link rel="stylesheet" href="css/app.css" />
<link rel="stylesheet" href="css/landing.css" />
<link rel="stylesheet" href="CulinaryCommand.styles.css" />
<link rel="icon" type="image/png" href="images/favicon.png" />
<link rel="icon" type="image/png" href="images/cc_favicon_green_clear2.png" />
@* <link rel="icon" type="image/png" href="images/cc_favicon_black2.png" /> *@
<HeadOutlet />
</head>

Expand Down
26 changes: 21 additions & 5 deletions CulinaryCommandApp/Components/Custom/LocationSelector.razor
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -59,22 +60,31 @@
@code {
private List<Location> 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<string>("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();
}

Expand All @@ -83,6 +93,7 @@
try
{
var json = await JS.InvokeAsync<string?>("localStorage.getItem", "cc_locations");

return string.IsNullOrWhiteSpace(json)
? new List<Location>()
: (JsonSerializer.Deserialize<List<Location>>(json) ?? new List<Location>());
Expand Down Expand Up @@ -139,4 +150,9 @@
{
NavigationManager.NavigateTo($"/settings/locations/{location.Id}");
}

public void Dispose()
{
LocationState.OnChange -= StateHasChanged;
}
}
8 changes: 8 additions & 0 deletions CulinaryCommandApp/Components/Custom/LogoutWidget.razor
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
@rendermode InteractiveServer
@inject NavigationManager Nav
@inject IJSRuntime JS
@inject LocationState LocationState



<button class="btn btn-outline-danger" @onclick="Logout">Logout</button>

@code {
private async Task Logout()
{
await JS.InvokeVoidAsync("localStorage.clear");
await JS.InvokeVoidAsync("sessionStorage.clear");
LocationState.FlushLocationState();

Nav.NavigateTo("/signin", true); // hard reload
}
}
11 changes: 10 additions & 1 deletion CulinaryCommandApp/Components/Custom/ProfileDropdown.razor
Original file line number Diff line number Diff line change
@@ -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

Expand Down Expand Up @@ -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);
}



Expand Down
2 changes: 1 addition & 1 deletion CulinaryCommandApp/Services/LocationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Expand Down
15 changes: 11 additions & 4 deletions CulinaryCommandApp/Services/LocationState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace CulinaryCommand.Services
{
public class LocationState
{
public const string ActiveLocStorageKey = "cc_activeLocationId";
private readonly IJSRuntime _js;
public List<Location> ManagedLocations { get; private set; } = new();
public Location? CurrentLocation { get; private set; }
Expand All @@ -23,7 +24,7 @@ public async Task HydrateAsync()
{
if (CurrentLocation != null) return; // Already have it

var savedId = await _js.InvokeAsync<string>("localStorage.getItem", "cc_selected_location_id");
var savedId = await _js.InvokeAsync<string>("localStorage.getItem", ActiveLocStorageKey);

if (!string.IsNullOrEmpty(savedId) && int.TryParse(savedId, out int id))
{
Expand All @@ -40,7 +41,7 @@ public async Task SetLocationsAsync(List<Location>? locations)
string? savedId = null;
try
{
savedId = await _js.InvokeAsync<string?>("localStorage.getItem", "cc_activeLocationId");
savedId = await _js.InvokeAsync<string?>("localStorage.getItem", ActiveLocStorageKey);
}
catch (InvalidOperationException)
{
Expand All @@ -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)
{
Expand All @@ -77,5 +78,11 @@ public async Task SetCurrentLocationAsync(Location? loc)
// OnChange?.Invoke();
NotifyStateChanged();
}

public void FlushLocationState()
{
ManagedLocations = new List<Location>();
CurrentLocation = null;
}
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added CulinaryCommandApp/wwwroot/images/favicon.ico
Binary file not shown.
Loading