OnProfNext/OnProfNext.Client/Components/Layout/MainLayout.razor
2025-10-15 13:29:50 +02:00

118 lines
2.6 KiB
Plaintext

@using OnProfNext.Client.Services
@inherits LayoutComponentBase
@inject NavigationManager Nav
@inject AuthService AuthService
<div class="page">
<div class="sidebar">
<NavMenu />
</div>
<main>
<div class="top-row px-4 d-flex align-items-center justify-content-between">
<div class="flex-grow-1">
<a class="fw-semibold text-decoration-none text-dark" href="/"> OnProf Next</a>
</div>
<div class="user-info d-flex align-items-center justify-content-end">
<span class="me-3 fw-semibold"> @username</span>
@if (username != "Gast")
{
<button class="btn btn-outline-secondary btn-sm" @onclick="Logout">Logout</button>
}
</div>
</div>
<article class="content px-4">
<div class="page-transition">
@Body
</div>
</article>
</main>
</div>
@code {
private string? username;
protected override async Task OnInitializedAsync()
{
AuthService.OnAuthStateChanged += async () => await LoadUsername();
await LoadUsername();
}
private async Task LoadUsername()
{
username = await AuthService.GetUsernameAsync();
if (string.IsNullOrEmpty(username))
username = "Gast";
await InvokeAsync(StateHasChanged);
}
private async Task Logout()
{
await AuthService.LogoutAsync();
Nav.NavigateTo("/login", forceLoad: true);
}
public void Dispose()
{
AuthService.OnAuthStateChanged -= async () => await LoadUsername();
}
}
<style>
.top-row {
background-color: #f8f9fa;
border-bottom: 1px solid #ddd;
height: 60px;
padding-right: 2rem;
padding-left: 2rem;
}
.top-row a {
color: #333;
text-decoration: none;
}
.top-row a:hover {
text-decoration: underline;
}
.top-row span {
font-size: 1rem;
color: #333;
}
.user-info {
min-width: 200px;
justify-content: flex-end;
}
.btn-outline-secondary {
border-radius: 0.4rem;
font-size: 0.9rem;
}
.page-transition {
animation: fadeIn 0.3s ease;
}
@@keyframes fadeIn {
from
{
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
</style>