feat(ui): Hub Navigation, Profile Dashboard and Auth Stability Fixes (#31)
This PR implements the Hub Navigation system and the Profile Dashboard, while resolving critical session synchronization issues. ### Key Changes - **Hub Navigation**: Introduced `MainHubLayout` with a premium glassmorphism sidebar, providing access to Dashboard, Library, Concepts Map, and Profile. - **Profile Dashboard**: Implemented a high-fidelity Profile page (#27) with learning metrics, AI token usage tracking, and system rank visualization. - **Stability Fixes**: - Resolved an infinite network loop on the `/profile` page by implementing request deduplication and in-memory caching in `IdentityService`. - Added environment-aware guards to prevent illegal JavaScript interop calls during server-side prerendering. - Implemented automatic session invalidation on `401 Unauthorized` responses to handle stale authentication states gracefully. - **Reader Integration**: Added a "Return to Dashboard" option in the reader toolbar (#26). Closes #26 Closes #27 Reviewed-on: #31 Co-authored-by: Marek Jasiński <jasins.marek@gmail.com> Co-committed-by: Marek Jasiński <jasins.marek@gmail.com>
This commit was merged in pull request #31.
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
|
||||
<div class="login-page-container">
|
||||
<div class="mesh-bg"></div>
|
||||
|
||||
|
||||
<div class="auth-card">
|
||||
<div class="auth-header">
|
||||
<div class="logo-box">
|
||||
@@ -21,9 +21,8 @@
|
||||
|
||||
<div class="social-auth">
|
||||
<button type="button" class="btn-google-auth" @onclick="HandleGoogleLogin">
|
||||
<img src="https://www.gstatic.com/images/branding/product/1x/gsa_512dp.png"
|
||||
alt="Google"
|
||||
style="width: 20px !important; height: 20px !important; flex-shrink: 0;" />
|
||||
<img src="https://www.gstatic.com/images/branding/product/1x/gsa_512dp.png" alt="Google"
|
||||
style="width: 20px !important; height: 20px !important; flex-shrink: 0;" />
|
||||
<span>Zaloguj się przez Google</span>
|
||||
</button>
|
||||
</div>
|
||||
@@ -47,7 +46,8 @@
|
||||
<div class="field-icon">
|
||||
<NexusIcon Name="lock" Size="18" />
|
||||
</div>
|
||||
<InputText id="password" type="@(_showPassword ? "text" : "password")" @bind-Value="_loginModel.Password" placeholder="Hasło" class="field-input" />
|
||||
<InputText id="password" type="@(_showPassword ? "text" : "password")"
|
||||
@bind-Value="_loginModel.Password" placeholder="Hasło" class="field-input" />
|
||||
<button type="button" class="toggle-visibility" @onclick="TogglePassword">
|
||||
<NexusIcon Name="@(_showPassword ? "eye-off" : "eye")" Size="18" />
|
||||
</button>
|
||||
@@ -84,7 +84,8 @@
|
||||
</div>
|
||||
|
||||
<div class="auth-legal">
|
||||
Korzystając z usługi, akceptujesz <a href="/terms">Regulamin</a> i <a href="/privacy">Politykę Prywatności</a>
|
||||
Korzystając z usługi, akceptujesz <a href="/terms">Regulamin</a> i <a href="/privacy">Politykę
|
||||
Prywatności</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -121,12 +122,24 @@
|
||||
|
||||
try
|
||||
{
|
||||
var success = await IdentityService.LoginAsync(_loginModel.Email, _loginModel.Password, _loginModel.RememberMe);
|
||||
if (success) NavigationManager.NavigateTo("/");
|
||||
else _errorMessage = "Nieprawidłowy e-mail lub hasło.";
|
||||
var result = await IdentityService.LoginAsync(_loginModel.Email, _loginModel.Password, _loginModel.RememberMe);
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
NavigationManager.NavigateTo("/");
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorMessage = result.Errors.FirstOrDefault()?.Message ?? "Nieprawidłowy e-mail lub hasło.";
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_errorMessage = $"Wystąpił błąd logowania: {ex.Message}.";
|
||||
}
|
||||
finally
|
||||
{
|
||||
_isSubmitting = false;
|
||||
}
|
||||
catch (Exception) { _errorMessage = "Wystąpił błąd logowania."; }
|
||||
finally { _isSubmitting = false; }
|
||||
}
|
||||
|
||||
private void HandleGoogleLogin() => NavigationManager.NavigateTo("identity/login/google", forceLoad: true);
|
||||
|
||||
Reference in New Issue
Block a user