add header in profile page
This commit is contained in:
@@ -14,6 +14,15 @@ public class AccountResponse : Account
|
||||
[JsonPropertyName("gender")]
|
||||
public GenderResponse? Gender { get; set; }
|
||||
|
||||
[JsonPropertyName("last_active")]
|
||||
public DateTime LastActive { get; set; }
|
||||
|
||||
[JsonPropertyName("creation_date")]
|
||||
public DateTime CreationDate { get; set; }
|
||||
|
||||
[JsonPropertyName("is_admin")]
|
||||
public bool IsAdmin { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -31,6 +40,9 @@ public class AccountResponse : Account
|
||||
Email = account.Email;
|
||||
Description = account.Description;
|
||||
Gender = account.Gender is not null ? new GenderResponse(account.Gender) : null;
|
||||
LastActive = account.LastActive;
|
||||
CreationDate = account.CreationDate;
|
||||
IsAdmin = account.IsAdmin;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -62,6 +62,9 @@ public class AccountsControllerService(
|
||||
RefreshToken = await refreshTokenTask,
|
||||
};
|
||||
|
||||
account.LastActive = DateTime.UtcNow;
|
||||
await database.SaveChangesAsync();
|
||||
|
||||
logger.LogInformation($"Account with ID {account.Id} was authenticated");
|
||||
return RequestResult.Ok(response);
|
||||
}
|
||||
@@ -91,6 +94,9 @@ public class AccountsControllerService(
|
||||
|
||||
string accessToken = await tokensService.CreateAccessTokenAsync(token.Account);
|
||||
|
||||
token.Account.LastActive = DateTime.UtcNow;
|
||||
await database.SaveChangesAsync();
|
||||
|
||||
logger.LogInformation($"Account with ID {token.AccountId} was authenticated by token refreshing");
|
||||
return RequestResult.Ok(new AuthenticateResponse
|
||||
{
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<link rel="stylesheet" href="css/panel.css?version=0.3.0.3"/>
|
||||
<link rel="stylesheet" href="css/main_button.css?version=0.3.0.0"/>
|
||||
<link rel="stylesheet" href="css/gaps.css?version=0.3.0.1"/>
|
||||
<link rel="stylesheet" href="WatchIt.Website.styles.css?version=0.3.0.22"/>
|
||||
<link rel="stylesheet" href="WatchIt.Website.styles.css?version=0.4.0.4"/>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
|
||||
<!-- BOOTSTRAP -->
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<div class="container-grid mt-grid">
|
||||
<div class="container-grid mt-header">
|
||||
<div class="row">
|
||||
<div class="col-auto">
|
||||
<PictureComponent Picture="@(_poster)" Placeholder="@(PosterPlaceholder)" AlternativeText="poster" Height="350"/>
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
/* CLASSES */
|
||||
|
||||
.mt-grid {
|
||||
margin-top: 9rem !important;
|
||||
}
|
||||
|
||||
.title-shadow {
|
||||
text-shadow: 2px 2px 2px #000;
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<img class="rounded-circle object-fit-cover @(Class)" alt="avatar" height="@(Size)" src="@(_picture is null ? "assets/user_placeholder.png" : _picture.ToString())"/>
|
||||
@@ -0,0 +1,58 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using WatchIt.Common.Model.Accounts;
|
||||
using WatchIt.Website.Services.Client.Accounts;
|
||||
|
||||
namespace WatchIt.Website.Components.Common.Subcomponents;
|
||||
|
||||
public partial class AccountPictureComponent : ComponentBase
|
||||
{
|
||||
#region SERVICES
|
||||
|
||||
[Inject] private IAccountsClientService AccountsClientService { get; set; } = default!;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region PARAMETERS
|
||||
|
||||
[Parameter] public required long Id { get; set; }
|
||||
[Parameter] public required int Size { get; set; }
|
||||
|
||||
[Parameter] public string Class { get; set; } = string.Empty;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region FIELDS
|
||||
|
||||
private AccountProfilePictureResponse? _picture;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region PRIVATE METHODS
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
List<Task> endTasks = new List<Task>();
|
||||
|
||||
// STEP 0
|
||||
endTasks.AddRange(
|
||||
[
|
||||
AccountsClientService.GetAccountProfilePicture(Id, data => _picture = data)
|
||||
]);
|
||||
|
||||
// END
|
||||
await Task.WhenAll(endTasks);
|
||||
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -34,7 +34,6 @@ public partial class DatabasePageComponent<TItem, TQuery> : ComponentBase where
|
||||
[Parameter] public Func<long, Task>? DeleteRatingMethod { get; set; }
|
||||
[Parameter] public required string PosterPlaceholder { get; set; }
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
<div id="base" class="vstack">
|
||||
<AccountPictureComponent Class="shadow position-absolute z-1 start-50 translate-middle" Id="@(AccountData.Id)" Size="240"/>
|
||||
<div class="panel z-0">
|
||||
<div class="vstack gap-3">
|
||||
<div id="space" class="container-grid"></div>
|
||||
<div class="d-flex justify-content-center">
|
||||
<h3 class="fw-bold">@(AccountData.Username)</h3>
|
||||
</div>
|
||||
@if (!string.IsNullOrWhiteSpace(AccountData.Description))
|
||||
{
|
||||
<span>
|
||||
@(AccountData.Description)
|
||||
</span>
|
||||
}
|
||||
<div class="d-flex flex-wrap justify-content-center metadata-pill-container">
|
||||
<div class="metadata-pill"><strong>Email:</strong> @(AccountData.Email)</div>
|
||||
@if (!string.IsNullOrWhiteSpace(AccountData.Gender?.Name))
|
||||
{
|
||||
<div class="metadata-pill"><strong>Gender:</strong> @(AccountData.Gender?.Name)</div>
|
||||
}
|
||||
<div class="metadata-pill"><strong>Account created:</strong> @(AccountData.CreationDate.ToShortDateString())</div>
|
||||
<div class="metadata-pill"><strong>Last active:</strong> @(AccountData.LastActive.ToShortDateString())</div>
|
||||
@if (AccountData.IsAdmin)
|
||||
{
|
||||
<div class="metadata-pill"><strong>Admin</strong></div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,7 +1,57 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using WatchIt.Common.Model.Accounts;
|
||||
using WatchIt.Website.Services.Authentication;
|
||||
using WatchIt.Website.Services.Client.Accounts;
|
||||
|
||||
namespace WatchIt.Website.Components.Pages.UserPage.Panels;
|
||||
|
||||
public partial class UserPageHeaderPanelComponent : ComponentBase
|
||||
{
|
||||
#region SERVICES
|
||||
|
||||
[Inject] private IAuthenticationService AuthenticationService { get; set; } = default!;
|
||||
[Inject] private IAccountsClientService AccountsClientService { get; set; } = default!;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region PARAMETERS
|
||||
|
||||
[Parameter] public required AccountResponse AccountData { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region FIELDS
|
||||
|
||||
private AccountProfilePictureResponse? _accountProfilePicture;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region PRIVATE METHODS
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
List<Task> endTasks = new List<Task>();
|
||||
|
||||
// STEP 0
|
||||
endTasks.AddRange(
|
||||
[
|
||||
AccountsClientService.GetAccountProfilePicture(AccountData.Id, data => _accountProfilePicture = data),
|
||||
]);
|
||||
|
||||
// END
|
||||
await Task.WhenAll(endTasks);
|
||||
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
/* IDS */
|
||||
|
||||
#base {
|
||||
margin-top: 120px;
|
||||
}
|
||||
|
||||
#space {
|
||||
height: 100px;
|
||||
}
|
||||
@@ -53,9 +53,9 @@
|
||||
else
|
||||
{
|
||||
<Dropdown RightAligned>
|
||||
<Button Color="Color.Default">
|
||||
<Button Color="Color.Default" Clicked="@(() => NavigationManager.NavigateTo("/user"))">
|
||||
<div class="d-flex gap-2 align-items-center">
|
||||
<img class="rounded-circle" alt="avatar" height="30" src="@(_userProfilePicture is null ? "assets/user_placeholder.png" : _userProfilePicture.ToString())"/>
|
||||
<AccountPictureComponent Id="@(_user.Id)" Size="30"/>
|
||||
<span>@(_user.Username)</span>
|
||||
</div>
|
||||
</Button>
|
||||
|
||||
@@ -18,7 +18,6 @@ public partial class MainLayout : LayoutComponentBase
|
||||
[Inject] public NavigationManager NavigationManager { get; set; } = default!;
|
||||
[Inject] public ITokensService TokensService { get; set; } = default!;
|
||||
[Inject] public IAuthenticationService AuthenticationService { get; set; } = default!;
|
||||
[Inject] public IAccountsClientService AccountsClientService { get; set; } = default!;
|
||||
[Inject] public IMediaClientService MediaClientService { get; set; } = default!;
|
||||
[Inject] public IPhotosClientService PhotosClientService { get; set; } = default!;
|
||||
|
||||
@@ -32,7 +31,6 @@ public partial class MainLayout : LayoutComponentBase
|
||||
|
||||
private User? _user;
|
||||
private PhotoResponse? _defaultBackgroundPhoto;
|
||||
private AccountProfilePictureResponse? _userProfilePicture;
|
||||
|
||||
private bool _searchbarVisible;
|
||||
private string _searchbarText = string.Empty;
|
||||
@@ -67,28 +65,14 @@ public partial class MainLayout : LayoutComponentBase
|
||||
if (firstRender)
|
||||
{
|
||||
List<Task> endTasks = new List<Task>();
|
||||
List<Task> step1Tasks = new List<Task>();
|
||||
|
||||
// STEP 0
|
||||
step1Tasks.AddRange(
|
||||
[
|
||||
Task.Run(async () => _user = await AuthenticationService.GetUserAsync())
|
||||
]);
|
||||
endTasks.AddRange(
|
||||
[
|
||||
Task.Run(async () => _user = await AuthenticationService.GetUserAsync()),
|
||||
PhotosClientService.GetPhotoRandomBackground(data => _defaultBackgroundPhoto = data)
|
||||
]);
|
||||
|
||||
// STEP 1
|
||||
await Task.WhenAll(step1Tasks);
|
||||
if (_user is not null)
|
||||
{
|
||||
endTasks.AddRange(
|
||||
[
|
||||
AccountsClientService.GetAccountProfilePicture(_user.Id, data => _userProfilePicture = data)
|
||||
]);
|
||||
}
|
||||
|
||||
// END
|
||||
await Task.WhenAll(endTasks);
|
||||
|
||||
|
||||
@@ -169,7 +169,7 @@ else
|
||||
<Tabs Pills
|
||||
RenderMode="TabsRenderMode.LazyLoad"
|
||||
SelectedTab="actors"
|
||||
Class="panel panel-menu panel-background-menu">
|
||||
Class="panel panel-menu panel-background-menu justify-content-center">
|
||||
<Items>
|
||||
<Tab Name="actors">Actors</Tab>
|
||||
<Tab Name="creators">Creators</Tab>
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
<Tabs Pills
|
||||
RenderMode="TabsRenderMode.LazyLoad"
|
||||
SelectedTab="actor"
|
||||
Class="panel panel-menu panel-background-menu">
|
||||
Class="panel panel-menu panel-background-menu justify-content-center">
|
||||
<Items>
|
||||
<Tab Name="actor">Actor</Tab>
|
||||
<Tab Name="creator">Creator</Tab>
|
||||
|
||||
@@ -40,9 +40,42 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="row">
|
||||
<div class="row mt-header">
|
||||
<div class="col">
|
||||
<UserPageHeaderPanelComponent/>
|
||||
<UserPageHeaderPanelComponent AccountData="@(_accountData)"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-over-panel-menu">
|
||||
<div class="col">
|
||||
<Tabs Pills
|
||||
RenderMode="TabsRenderMode.LazyLoad"
|
||||
SelectedTab="summary"
|
||||
Class="panel panel-menu panel-background-menu justify-content-center">
|
||||
<Items>
|
||||
<Tab Name="summary">Summary</Tab>
|
||||
<Tab Name="movies">Movies</Tab>
|
||||
<Tab Name="series">TV Series</Tab>
|
||||
<Tab Name="people">People</Tab>
|
||||
<Tab Name="people">Roles</Tab>
|
||||
</Items>
|
||||
<Content>
|
||||
<TabPanel Name="summary">
|
||||
|
||||
</TabPanel>
|
||||
<TabPanel Name="movies">
|
||||
|
||||
</TabPanel>
|
||||
<TabPanel Name="series">
|
||||
|
||||
</TabPanel>
|
||||
<TabPanel Name="people">
|
||||
|
||||
</TabPanel>
|
||||
<TabPanel Name="roles">
|
||||
|
||||
</TabPanel>
|
||||
</Content>
|
||||
</Tabs>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
/* DEFAULT */
|
||||
|
||||
.mt-header {
|
||||
margin-top: 9rem !important;
|
||||
}
|
||||
|
||||
.mt-default {
|
||||
margin-top: 1rem !important;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user