add header in profile page
This commit is contained in:
@@ -14,6 +14,15 @@ public class AccountResponse : Account
|
|||||||
[JsonPropertyName("gender")]
|
[JsonPropertyName("gender")]
|
||||||
public GenderResponse? Gender { get; set; }
|
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
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
@@ -31,6 +40,9 @@ public class AccountResponse : Account
|
|||||||
Email = account.Email;
|
Email = account.Email;
|
||||||
Description = account.Description;
|
Description = account.Description;
|
||||||
Gender = account.Gender is not null ? new GenderResponse(account.Gender) : null;
|
Gender = account.Gender is not null ? new GenderResponse(account.Gender) : null;
|
||||||
|
LastActive = account.LastActive;
|
||||||
|
CreationDate = account.CreationDate;
|
||||||
|
IsAdmin = account.IsAdmin;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@@ -62,6 +62,9 @@ public class AccountsControllerService(
|
|||||||
RefreshToken = await refreshTokenTask,
|
RefreshToken = await refreshTokenTask,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
account.LastActive = DateTime.UtcNow;
|
||||||
|
await database.SaveChangesAsync();
|
||||||
|
|
||||||
logger.LogInformation($"Account with ID {account.Id} was authenticated");
|
logger.LogInformation($"Account with ID {account.Id} was authenticated");
|
||||||
return RequestResult.Ok(response);
|
return RequestResult.Ok(response);
|
||||||
}
|
}
|
||||||
@@ -91,6 +94,9 @@ public class AccountsControllerService(
|
|||||||
|
|
||||||
string accessToken = await tokensService.CreateAccessTokenAsync(token.Account);
|
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");
|
logger.LogInformation($"Account with ID {token.AccountId} was authenticated by token refreshing");
|
||||||
return RequestResult.Ok(new AuthenticateResponse
|
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/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/main_button.css?version=0.3.0.0"/>
|
||||||
<link rel="stylesheet" href="css/gaps.css?version=0.3.0.1"/>
|
<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">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||||
|
|
||||||
<!-- BOOTSTRAP -->
|
<!-- BOOTSTRAP -->
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<div class="container-grid mt-grid">
|
<div class="container-grid mt-header">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
<PictureComponent Picture="@(_poster)" Placeholder="@(PosterPlaceholder)" AlternativeText="poster" Height="350"/>
|
<PictureComponent Picture="@(_poster)" Placeholder="@(PosterPlaceholder)" AlternativeText="poster" Height="350"/>
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
/* CLASSES */
|
/* CLASSES */
|
||||||
|
|
||||||
.mt-grid {
|
|
||||||
margin-top: 9rem !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title-shadow {
|
.title-shadow {
|
||||||
text-shadow: 2px 2px 2px #000;
|
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
|
||||||
|
}
|
||||||
@@ -33,7 +33,6 @@ public partial class DatabasePageComponent<TItem, TQuery> : ComponentBase where
|
|||||||
[Parameter] public Func<long, RatingRequest, Task>? PutRatingMethod { get; set; }
|
[Parameter] public Func<long, RatingRequest, Task>? PutRatingMethod { get; set; }
|
||||||
[Parameter] public Func<long, Task>? DeleteRatingMethod { get; set; }
|
[Parameter] public Func<long, Task>? DeleteRatingMethod { get; set; }
|
||||||
[Parameter] public required string PosterPlaceholder { get; set; }
|
[Parameter] public required string PosterPlaceholder { get; set; }
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#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 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;
|
namespace WatchIt.Website.Components.Pages.UserPage.Panels;
|
||||||
|
|
||||||
public partial class UserPageHeaderPanelComponent : ComponentBase
|
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,14 +53,14 @@
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
<Dropdown RightAligned>
|
<Dropdown RightAligned>
|
||||||
<Button Color="Color.Default">
|
<Button Color="Color.Default" Clicked="@(() => NavigationManager.NavigateTo("/user"))">
|
||||||
<div class="d-flex gap-2 align-items-center">
|
<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>
|
<span>@(_user.Username)</span>
|
||||||
</div>
|
</div>
|
||||||
</Button>
|
</Button>
|
||||||
<DropdownToggle Color="Color.Default" Split />
|
<DropdownToggle Color="Color.Default" Split />
|
||||||
<DropdownMenu >
|
<DropdownMenu>
|
||||||
<DropdownItem Clicked="@(() => NavigationManager.NavigateTo("/user"))">Your profile</DropdownItem>
|
<DropdownItem Clicked="@(() => NavigationManager.NavigateTo("/user"))">Your profile</DropdownItem>
|
||||||
@if (_user.IsAdmin)
|
@if (_user.IsAdmin)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ public partial class MainLayout : LayoutComponentBase
|
|||||||
[Inject] public NavigationManager NavigationManager { get; set; } = default!;
|
[Inject] public NavigationManager NavigationManager { get; set; } = default!;
|
||||||
[Inject] public ITokensService TokensService { get; set; } = default!;
|
[Inject] public ITokensService TokensService { get; set; } = default!;
|
||||||
[Inject] public IAuthenticationService AuthenticationService { 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 IMediaClientService MediaClientService { get; set; } = default!;
|
||||||
[Inject] public IPhotosClientService PhotosClientService { get; set; } = default!;
|
[Inject] public IPhotosClientService PhotosClientService { get; set; } = default!;
|
||||||
|
|
||||||
@@ -32,7 +31,6 @@ public partial class MainLayout : LayoutComponentBase
|
|||||||
|
|
||||||
private User? _user;
|
private User? _user;
|
||||||
private PhotoResponse? _defaultBackgroundPhoto;
|
private PhotoResponse? _defaultBackgroundPhoto;
|
||||||
private AccountProfilePictureResponse? _userProfilePicture;
|
|
||||||
|
|
||||||
private bool _searchbarVisible;
|
private bool _searchbarVisible;
|
||||||
private string _searchbarText = string.Empty;
|
private string _searchbarText = string.Empty;
|
||||||
@@ -67,28 +65,14 @@ public partial class MainLayout : LayoutComponentBase
|
|||||||
if (firstRender)
|
if (firstRender)
|
||||||
{
|
{
|
||||||
List<Task> endTasks = new List<Task>();
|
List<Task> endTasks = new List<Task>();
|
||||||
List<Task> step1Tasks = new List<Task>();
|
|
||||||
|
|
||||||
// STEP 0
|
// STEP 0
|
||||||
step1Tasks.AddRange(
|
|
||||||
[
|
|
||||||
Task.Run(async () => _user = await AuthenticationService.GetUserAsync())
|
|
||||||
]);
|
|
||||||
endTasks.AddRange(
|
endTasks.AddRange(
|
||||||
[
|
[
|
||||||
|
Task.Run(async () => _user = await AuthenticationService.GetUserAsync()),
|
||||||
PhotosClientService.GetPhotoRandomBackground(data => _defaultBackgroundPhoto = data)
|
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
|
// END
|
||||||
await Task.WhenAll(endTasks);
|
await Task.WhenAll(endTasks);
|
||||||
|
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ else
|
|||||||
<Tabs Pills
|
<Tabs Pills
|
||||||
RenderMode="TabsRenderMode.LazyLoad"
|
RenderMode="TabsRenderMode.LazyLoad"
|
||||||
SelectedTab="actors"
|
SelectedTab="actors"
|
||||||
Class="panel panel-menu panel-background-menu">
|
Class="panel panel-menu panel-background-menu justify-content-center">
|
||||||
<Items>
|
<Items>
|
||||||
<Tab Name="actors">Actors</Tab>
|
<Tab Name="actors">Actors</Tab>
|
||||||
<Tab Name="creators">Creators</Tab>
|
<Tab Name="creators">Creators</Tab>
|
||||||
|
|||||||
@@ -44,7 +44,7 @@
|
|||||||
<Tabs Pills
|
<Tabs Pills
|
||||||
RenderMode="TabsRenderMode.LazyLoad"
|
RenderMode="TabsRenderMode.LazyLoad"
|
||||||
SelectedTab="actor"
|
SelectedTab="actor"
|
||||||
Class="panel panel-menu panel-background-menu">
|
Class="panel panel-menu panel-background-menu justify-content-center">
|
||||||
<Items>
|
<Items>
|
||||||
<Tab Name="actor">Actor</Tab>
|
<Tab Name="actor">Actor</Tab>
|
||||||
<Tab Name="creator">Creator</Tab>
|
<Tab Name="creator">Creator</Tab>
|
||||||
|
|||||||
@@ -40,9 +40,42 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<div class="row">
|
<div class="row mt-header">
|
||||||
<div class="col">
|
<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>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
/* DEFAULT */
|
/* DEFAULT */
|
||||||
|
|
||||||
|
.mt-header {
|
||||||
|
margin-top: 9rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
.mt-default {
|
.mt-default {
|
||||||
margin-top: 1rem !important;
|
margin-top: 1rem !important;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user