@page "/" @page "/dashboard" @using Microsoft.AspNetCore.Authorization @using NexusReader.UI.Shared.Components.Atoms @using NexusReader.UI.Shared.Components.Organisms @using NexusReader.UI.Shared.Services @inject IIdentityService IdentityService @inject NavigationManager NavigationManager @inject ISyncService SyncService @attribute [Authorize] @implements IDisposable Dashboard | Nexus Reader
Profile

@(string.IsNullOrEmpty(_profile?.DisplayName) ? (_profile?.Email.Split('@')[0] ?? "Użytkownik") : _profile.DisplayName)

Książki: @(_profile?.BooksReadCount ?? 0)
Pojęcia: @(_profile?.ConceptsMappedCount ?? 0)
Średni Wynik: @(_profile?.AverageQuizScore ?? 0)%

Witaj, @(string.IsNullOrEmpty(_profile?.DisplayName) ? (_profile?.Email.Split('@')[0] ?? "Użytkowniku") : _profile.DisplayName)

Integracja Wiedzy

@if (_profile?.MappedConcepts != null && _profile.MappedConcepts.Any()) { @for (int i = 0; i < _profile.MappedConcepts.Count; i++) { var concept = _profile.MappedConcepts[i]; var angle = i * (360.0 / _profile.MappedConcepts.Count); var dist = 65;
} } else {
}
@(string.IsNullOrEmpty(_hoveredConceptLabel) ? "TU JESTEŚ" : _hoveredConceptLabel)
@if (_hoveredConcept != null) {
@_hoveredConcept.Type

@_hoveredConcept.Content

} else {
Mapowanie AI

Najedź na węzeł, aby zbadać pojęcie wydobyte przez Nexus AI.

}

Rozwiązane Quizy

@if (_profile?.RecentQuizzes != null && _profile.RecentQuizzes.Any()) {
@foreach (var quiz in _profile.RecentQuizzes) {
@quiz.Topic = 50 ? "badge-warning" : "badge-danger")"> @quiz.Score / @quiz.TotalQuestions (@((int)quiz.Percentage)%)
@quiz.CompletedDate.ToString("g")
}
} else {

Brak rozwiązanych quizów

Rozwiązuj quizy w trakcie czytania książek, aby śledzić swoje postępy.

}

Architektura Systemu Nexus

.NET 10 & Blazor Hybrid Architecture

Nasza platforma została zaprojektowana w oparciu o najnowszy stos technologiczny .NET 10 oraz model komponentowy Blazor, zapewniając pełną kompatybilność z kompilacją Native AOT (Ahead-Of-Time). Dzięki temu aplikacja charakteryzuje się błyskawicznym czasu uruchamiania i minimalnym zużyciem pamięci, co jest kluczowe w scenariuszach mobilnych i hybrydowych.

Wykorzystanie wzorca CQRS (Command Query Responsibility Segregation) wraz z biblioteką MediatR oddziela operacje odczytu od zapisu, gwarantując skalowalność i przejrzystość kodu. Wszystkie operacje biznesowe są reprezentowane przez niezależne procedury obsługi (handlers) zwracające unifikowany typ wyniku Result<T>, eliminując rzucanie wyjątków dla przepływów sterowania.

Warstwa prezentacji opiera się na izolowanych komponentach Razor z dedykowanymi arkuszami stylów CSS, co ułatwia zarządzanie modularnym i rozszerzalnym interfejsem użytkownika w duchu Modern Deep Dark.

@code { private UserProfileDto? _profile; private MappedConceptDto? _hoveredConcept; private string _hoveredConceptLabel = string.Empty; protected override async Task OnInitializedAsync() { IdentityService.OnStateInvalidated += HandleStateInvalidatedAsync; await LoadProfileAsync(); await SyncService.InitializeAsync(); SyncService.OnProgressReceived += HandleProgressReceivedAsync; } private void SetHoveredConcept(MappedConceptDto concept) { _hoveredConcept = concept; _hoveredConceptLabel = concept.DisplayLabel; } private void ClearHoveredConcept() { _hoveredConcept = null; _hoveredConceptLabel = string.Empty; } private async Task LoadProfileAsync() { var result = await IdentityService.GetProfileAsync(); if (result.IsSuccess) { _profile = result.Value; } else { _profile = null; } StateHasChanged(); } private async Task HandleStateInvalidatedAsync() { await InvokeAsync(async () => { await LoadProfileAsync(); }); } private async Task HandleProgressReceivedAsync(string pageId, DateTime timestamp) { await InvokeAsync(async () => { IdentityService.ClearCache(); await LoadProfileAsync(); }); } public void Dispose() { IdentityService.OnStateInvalidated -= HandleStateInvalidatedAsync; SyncService.OnProgressReceived -= HandleProgressReceivedAsync; } }