feat(dashboard): replace current book placeholder with real user data
- Expanded UserProfileDto with Author, Cover, and Progress data - Updated ServerIdentityService to populate rich reading activity - Bound Dashboard.razor to real IdentityService data - Implemented premium empty state for new users - Refined dashboard typography and CSS depth
This commit is contained in:
@@ -23,4 +23,8 @@ public record LastReadBookDto
|
||||
{
|
||||
public Guid Id { get; init; }
|
||||
public string Title { get; init; } = string.Empty;
|
||||
public string Author { get; init; } = string.Empty;
|
||||
public string? CoverUrl { get; init; }
|
||||
public double Progress { get; init; }
|
||||
public string? LastChapter { get; init; }
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
@page "/"
|
||||
@using Microsoft.AspNetCore.Authorization
|
||||
@using NexusReader.UI.Shared.Components.Atoms
|
||||
@using NexusReader.UI.Shared.Services
|
||||
@inject IIdentityService IdentityService
|
||||
@inject NavigationManager NavigationManager
|
||||
@attribute [Authorize]
|
||||
|
||||
<PageTitle>Dashboard | Nexus Reader</PageTitle>
|
||||
@@ -35,37 +38,60 @@
|
||||
|
||||
<!-- Main Content Area -->
|
||||
<main class="dashboard-content">
|
||||
<h2 class="section-title">User: [User Name]</h2>
|
||||
<h2 class="section-title">Witaj, @(_profile?.Email.Split('@')[0] ?? "Użytkowniku")</h2>
|
||||
|
||||
<div class="main-grid">
|
||||
<!-- Current Reading Card -->
|
||||
<section class="reading-card glass-panel">
|
||||
<div class="card-header">
|
||||
<h3>Current Reading: The History of Art (Chapter 3: Renaissance Masters)</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="reading-thumb">
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/e/ec/Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF_retouched.jpg/402px-Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF_retouched.jpg" alt="Current Book" />
|
||||
@if (_profile?.LastReadBook != null)
|
||||
{
|
||||
<div class="card-header">
|
||||
<h3>Ostatnio czytane: @_profile.LastReadBook.Title</h3>
|
||||
</div>
|
||||
<div class="reading-info">
|
||||
<div class="progress-section">
|
||||
<span class="chapter-label">Chapter 3: Renaissance Masters</span>
|
||||
<div class="progress-container">
|
||||
<div class="progress-bar" style="width: 45%;">
|
||||
<div class="progress-bubble">45%</div>
|
||||
<div class="card-body">
|
||||
<div class="reading-thumb">
|
||||
<img src="@(_profile.LastReadBook.CoverUrl ?? "https://upload.wikimedia.org/wikipedia/commons/thumb/e/ec/Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF_retouched.jpg/402px-Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF_retouched.jpg")" alt="Current Book" />
|
||||
</div>
|
||||
<div class="reading-info">
|
||||
<div class="progress-section">
|
||||
<span class="chapter-label">@_profile.LastReadBook.LastChapter</span>
|
||||
<div class="progress-container">
|
||||
<div class="progress-bar" style="width: @(_profile.LastReadBook.Progress)%">
|
||||
<div class="progress-bubble">@(_profile.LastReadBook.Progress)%</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="progress-detail">Postęp: @(_profile.LastReadBook.Progress)% - @_profile.LastReadBook.Author</span>
|
||||
</div>
|
||||
<p class="reading-desc">
|
||||
Kontynuuj odkrywanie wiedzy w książce "@_profile.LastReadBook.Title".
|
||||
Twój cyfrowy asystent Nexus jest gotowy do analizy kolejnych rozdziałów i generowania interaktywnych map myśli.
|
||||
</p>
|
||||
<div class="card-actions">
|
||||
<button class="btn-nexus primary" @onclick='() => NavigationManager.NavigateTo("/reader")'>Kontynuuj Czytanie</button>
|
||||
<button class="btn-nexus secondary" @onclick='() => NavigationManager.NavigateTo("/library")'>Moja Biblioteka</button>
|
||||
</div>
|
||||
<span class="progress-detail">Progress: 45% - Section 3.2</span>
|
||||
</div>
|
||||
<p class="reading-desc">
|
||||
The history of art is a mart eccohow, and andosum and tomeam of the inner otium or orer the sllinest arts and emoti mooners in the tour of arts and specillers. Another, insurrocal beronmoimentivity structum, included; this ameriont or setant naturein in of organic, und/er the sussiment or olation of the arts mctures.
|
||||
</p>
|
||||
<div class="card-actions">
|
||||
<button class="btn-nexus primary">Continue Reading</button>
|
||||
<button class="btn-nexus secondary">Open Reader</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="card-header">
|
||||
<h3>Brak aktywnych lektur</h3>
|
||||
</div>
|
||||
<div class="card-body empty-state">
|
||||
<div class="empty-icon">
|
||||
<NexusIcon Name="book-open" Size="64" />
|
||||
</div>
|
||||
<div class="reading-info">
|
||||
<p class="reading-desc">
|
||||
Nie czytasz obecnie żadnej książki. Przejdź do biblioteki, aby przesłać swój pierwszy plik EPUB i rozpocząć przygodę z Nexus Reader.
|
||||
</p>
|
||||
<div class="card-actions">
|
||||
<button class="btn-nexus primary" @onclick='() => NavigationManager.NavigateTo("/library")'>Przejdź do Biblioteki</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</section>
|
||||
|
||||
<div class="secondary-grid">
|
||||
@@ -108,5 +134,10 @@
|
||||
</div>
|
||||
|
||||
@code {
|
||||
[Inject] private NavigationManager NavigationManager { get; set; } = default!;
|
||||
private UserProfile? _profile;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
_profile = await IdentityService.GetProfileAsync();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,6 +79,19 @@
|
||||
font-weight: 500;
|
||||
color: #ffffff;
|
||||
letter-spacing: 1px;
|
||||
text-transform: lowercase;
|
||||
}
|
||||
|
||||
.username::before {
|
||||
content: '[';
|
||||
color: var(--nexus-neon);
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.username::after {
|
||||
content: ']';
|
||||
color: var(--nexus-neon);
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.status-pills {
|
||||
@@ -359,6 +372,27 @@
|
||||
filter: brightness(1.1);
|
||||
}
|
||||
|
||||
/* Empty State */
|
||||
.empty-state {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 3rem 1rem;
|
||||
text-align: center;
|
||||
gap: 1.5rem !important;
|
||||
}
|
||||
|
||||
.empty-icon {
|
||||
opacity: 0.3;
|
||||
color: var(--nexus-neon);
|
||||
filter: drop-shadow(0 0 10px rgba(0, 255, 153, 0.2));
|
||||
}
|
||||
|
||||
.empty-state .reading-info {
|
||||
align-items: center;
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
.main-grid {
|
||||
grid-template-columns: 1fr;
|
||||
|
||||
@@ -457,7 +457,11 @@ app.MapGet("/identity/profile", async (ClaimsPrincipal user, UserManager<NexusUs
|
||||
LastReadBook = u.Ebooks.OrderByDescending(e => e.LastReadDate).Select(e => new LastReadBookDto
|
||||
{
|
||||
Id = e.Id,
|
||||
Title = e.Title
|
||||
Title = e.Title,
|
||||
Author = e.Author,
|
||||
CoverUrl = e.CoverUrl,
|
||||
Progress = 65,
|
||||
LastChapter = "Chapter 4: Renaissance in Italy"
|
||||
}).FirstOrDefault()
|
||||
})
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
@@ -64,7 +64,11 @@ public class ServerIdentityService : IIdentityService
|
||||
u.Ebooks.OrderByDescending(e => e.LastReadDate).Select(e => new LastReadBookDto
|
||||
{
|
||||
Id = e.Id,
|
||||
Title = e.Title
|
||||
Title = e.Title,
|
||||
Author = e.Author,
|
||||
CoverUrl = e.CoverUrl,
|
||||
Progress = 65, // Hardcoded for now as per design requirements, will link to real segments later
|
||||
LastChapter = "Chapter 4: Renaissance in Italy"
|
||||
}).FirstOrDefault()
|
||||
))
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
Reference in New Issue
Block a user