Files
Nexus.Reader/src/NexusReader.UI.Shared/Layout/ReaderLayout.razor
T
mjasin 5fdc89dbf3 feat(ui): implement hub navigation, profile dashboard and fix auth sync loop
- Added MainHubLayout with glassmorphism sidebar
- Implemented Profile dashboard with learn metrics
- Added request deduplication and caching to IdentityService
- Fixed infinite redirect loop on /profile page
- Added dashboard navigation from reader
- Closes #26, Closes #27
2026-05-10 09:28:40 +02:00

117 lines
3.8 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@inherits LayoutComponentBase
@using NexusReader.Application.Abstractions.Services
@using NexusReader.UI.Shared.Services
@using NexusReader.UI.Shared.Components.Molecules
@using NexusReader.UI.Shared.Components.Organisms
@using Microsoft.Extensions.Logging
@inject IPlatformService PlatformService
@inject IFocusModeService FocusMode
@inject IQuizStateService QuizService
@inject IJSRuntime JS
@inject IIdentityService IdentityService
@inject NavigationManager NavigationManager
@inject Microsoft.Extensions.Logging.ILogger<ReaderLayout> Logger
@implements IDisposable
<div class="app-container @_platformClass @(FocusMode.IsFocusModeActive ? "focus-mode-active" : "")">
<div class="reader-pane">
<main>
@Body
</main>
<AuthorizeView>
<Authorized>
<ReaderFooter />
</Authorized>
</AuthorizeView>
</div>
<AuthorizeView>
<Authorized>
<div class="resizer" id="sidebar-resizer"></div>
<div class="intelligence-sidebar">
<IntelligenceToolbar />
<div class="intelligence-content">
<div class="intelligence-header">
<div class="ai-title">
<NexusIcon Name="robot" Size="20"
Class="@($"neon-glow {(QuizService.HasNewQuiz ? "quiz-available" : "")}")" />
<span>Asystent AI</span>
</div>
<button class="close-btn">×</button>
</div>
<div class="intelligence-scroll-area">
@if (!_isMobile)
{
<KnowledgeGraph />
}
<KnowledgeCheck />
</div>
</div>
</div>
</Authorized>
<Authorizing>
<div class="app-preloader">
<div class="preloader-spinner"></div>
<div class="preloader-text">Weryfikacja...</div>
</div>
</Authorizing>
</AuthorizeView>
</div>
<div id="blazor-error-ui" data-nosnippet>
An unhandled error has occurred.
<a href="." class="reload">Reload</a>
<span class="dismiss">🗙</span>
</div>
@code {
private string _platformClass = "platform-desktop";
private bool _isMobile = false;
protected override void OnInitialized()
{
FocusMode.OnFocusModeChanged += HandleUpdate;
QuizService.OnQuizUpdated += HandleUpdate;
var context = PlatformService.GetDeviceContext();
if (context.IsSuccess)
{
_isMobile = context.Value.DeviceType switch
{
DeviceType.Phone or DeviceType.Tablet => true,
_ => false
};
_platformClass = _isMobile ? "platform-mobile" : "platform-desktop";
}
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
try
{
var module = await JS.InvokeAsync<IJSObjectReference>("import", "./_content/NexusReader.UI.Shared/js/layoutResizer.js");
await module.InvokeVoidAsync("initResizer", ".app-container", "#sidebar-resizer", "--sidebar-width");
}
catch (Exception ex)
{
Logger.LogError(ex, "Failed to initialize layout resizer JS module.");
}
}
}
private Task HandleUpdate() => InvokeAsync(StateHasChanged);
public void Dispose()
{
FocusMode.OnFocusModeChanged -= HandleUpdate;
QuizService.OnQuizUpdated -= HandleUpdate;
}
}