UserPage - Lists of rated movies and tv series added
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
using WatchIt.Common.Model.Accounts;
|
||||
using WatchIt.Common.Model.Movies;
|
||||
using WatchIt.Common.Model.Series;
|
||||
using WatchIt.Common.Services.HttpClient;
|
||||
using WatchIt.Website.Services.Configuration;
|
||||
using WatchIt.Website.Services.Tokens;
|
||||
@@ -78,9 +80,9 @@ public class AccountsClientService(IHttpClientService httpClientService, IConfig
|
||||
.ExecuteAction();
|
||||
}
|
||||
|
||||
public async Task GetAccountInfoById(long id, Action<AccountResponse>? successAction = null, Action? notFoundAction = null)
|
||||
public async Task GetAccountInfo(long id, Action<AccountResponse>? successAction = null, Action? notFoundAction = null)
|
||||
{
|
||||
string url = GetUrl(EndpointsConfiguration.Accounts.GetAccountInfoById, id);
|
||||
string url = GetUrl(EndpointsConfiguration.Accounts.GetAccountInfo, id);
|
||||
HttpRequest request = new HttpRequest(HttpMethodType.Get, url);
|
||||
|
||||
HttpResponse response = await httpClientService.SendRequestAsync(request);
|
||||
@@ -89,18 +91,6 @@ public class AccountsClientService(IHttpClientService httpClientService, IConfig
|
||||
.ExecuteAction();
|
||||
}
|
||||
|
||||
public async Task GetAccountInfo(Action<AccountResponse>? successAction = null, Action? unauthorizedAction = null, Action? notFoundAction = null)
|
||||
{
|
||||
string url = GetUrl(EndpointsConfiguration.Accounts.GetAccountInfo);
|
||||
HttpRequest request = new HttpRequest(HttpMethodType.Get, url);
|
||||
|
||||
HttpResponse response = await httpClientService.SendRequestAsync(request);
|
||||
response.RegisterActionFor2XXSuccess(successAction)
|
||||
.RegisterActionFor401Unauthorized(unauthorizedAction)
|
||||
.RegisterActionFor404NotFound(notFoundAction)
|
||||
.ExecuteAction();
|
||||
}
|
||||
|
||||
public async Task PutAccountInfo(AccountRequest data, Action<AccountResponse>? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? unauthorizedAction = null, Action? notFoundAction = null)
|
||||
{
|
||||
string url = GetUrl(EndpointsConfiguration.Accounts.PutAccountInfo);
|
||||
@@ -117,6 +107,34 @@ public class AccountsClientService(IHttpClientService httpClientService, IConfig
|
||||
.ExecuteAction();
|
||||
}
|
||||
|
||||
public async Task GetAccountRatedMovies(long id, MovieRatedQueryParameters query, Action<IEnumerable<MovieRatedResponse>>? successAction = null, Action? notFoundAction = null)
|
||||
{
|
||||
string url = GetUrl(EndpointsConfiguration.Accounts.GetAccountRatedMovies, id);
|
||||
HttpRequest request = new HttpRequest(HttpMethodType.Get, url)
|
||||
{
|
||||
Query = query
|
||||
};
|
||||
|
||||
HttpResponse response = await httpClientService.SendRequestAsync(request);
|
||||
response.RegisterActionFor2XXSuccess(successAction)
|
||||
.RegisterActionFor404NotFound(notFoundAction)
|
||||
.ExecuteAction();
|
||||
}
|
||||
|
||||
public async Task GetAccountRatedSeries(long id, SeriesRatedQueryParameters query, Action<IEnumerable<SeriesRatedResponse>>? successAction = null, Action? notFoundAction = null)
|
||||
{
|
||||
string url = GetUrl(EndpointsConfiguration.Accounts.GetAccountRatedSeries, id);
|
||||
HttpRequest request = new HttpRequest(HttpMethodType.Get, url)
|
||||
{
|
||||
Query = query
|
||||
};
|
||||
|
||||
HttpResponse response = await httpClientService.SendRequestAsync(request);
|
||||
response.RegisterActionFor2XXSuccess(successAction)
|
||||
.RegisterActionFor404NotFound(notFoundAction)
|
||||
.ExecuteAction();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using WatchIt.Common.Model.Accounts;
|
||||
using WatchIt.Common.Model.Movies;
|
||||
using WatchIt.Common.Model.Series;
|
||||
|
||||
namespace WatchIt.Website.Services.Client.Accounts;
|
||||
|
||||
@@ -9,7 +11,8 @@ public interface IAccountsClientService
|
||||
Task AuthenticateRefresh(Action<AuthenticateResponse>? successAction = null, Action? unauthorizedAction = null, Action? forbiddenAction = null);
|
||||
Task Logout(Action? successAction = null);
|
||||
Task GetAccountProfilePicture(long id, Action<AccountProfilePictureResponse>? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? notFoundAction = null);
|
||||
Task GetAccountInfoById(long id, Action<AccountResponse>? successAction = null, Action? notFoundAction = null);
|
||||
Task GetAccountInfo(Action<AccountResponse>? successAction = null, Action? unauthorizedAction = null, Action? notFoundAction = null);
|
||||
Task GetAccountInfo(long id, Action<AccountResponse>? successAction = null, Action? notFoundAction = null);
|
||||
Task PutAccountInfo(AccountRequest data, Action<AccountResponse>? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? unauthorizedAction = null, Action? notFoundAction = null);
|
||||
Task GetAccountRatedMovies(long id, MovieRatedQueryParameters query, Action<IEnumerable<MovieRatedResponse>>? successAction = null, Action? notFoundAction = null);
|
||||
Task GetAccountRatedSeries(long id, SeriesRatedQueryParameters query, Action<IEnumerable<SeriesRatedResponse>>? successAction = null, Action? notFoundAction = null);
|
||||
}
|
||||
@@ -8,7 +8,8 @@ public class Accounts
|
||||
public string AuthenticateRefresh { get; set; }
|
||||
public string Logout { get; set; }
|
||||
public string GetProfilePicture { get; set; }
|
||||
public string GetAccountInfoById { get; set; }
|
||||
public string GetAccountInfo { get; set; }
|
||||
public string PutAccountInfo { get; set; }
|
||||
public string GetAccountRatedMovies { get; set; }
|
||||
public string GetAccountRatedSeries { get; set; }
|
||||
}
|
||||
@@ -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.4.0.4"/>
|
||||
<link rel="stylesheet" href="WatchIt.Website.styles.css?version=0.4.0.12"/>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
|
||||
<!-- BOOTSTRAP -->
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using WatchIt.Common.Query;
|
||||
|
||||
namespace WatchIt.Website.Components.Pages.DatabasePage.Subcomponents;
|
||||
namespace WatchIt.Website.Components.Common.ListComponent;
|
||||
|
||||
public abstract class FilterFormComponent<TItem, TQuery> : ComponentBase where TItem : IQueryOrderable<TItem> where TQuery : QueryParameters<TItem>
|
||||
{
|
||||
#region PARAMETERS
|
||||
|
||||
[CascadingParameter]
|
||||
protected DatabasePageComponent<TItem, TQuery> Parent { get; set; }
|
||||
protected ListComponent<TItem, TQuery> Parent { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -60,6 +60,8 @@
|
||||
PosterPlaceholder="@(PosterPlaceholder)"
|
||||
PosterDownloadingTask="@(action => PictureDownloadingTask(id, action))"
|
||||
GlobalRating="@(RatingSource(item))"
|
||||
SecondaryRating="@(SecondaryRatingSource?.Invoke(item))"
|
||||
SecondaryRatingTitle="@(SecondaryRatingTitle)"
|
||||
GetGlobalRatingMethod="@(action => GetGlobalRatingMethod(id, action))"
|
||||
GetUserRatingMethod="@(GetUserRatingMethod is not null ? (user, actionSuccess, actionNotFound) => GetUserRatingMethod(id, user, actionSuccess, actionNotFound) : null)"
|
||||
PutRatingMethod="@(PutRatingMethod is not null ? (request) => PutRatingMethod(id, request) : null)"
|
||||
@@ -4,9 +4,9 @@ using WatchIt.Common.Model.Movies;
|
||||
using WatchIt.Common.Model.Rating;
|
||||
using WatchIt.Common.Query;
|
||||
|
||||
namespace WatchIt.Website.Components.Pages.DatabasePage;
|
||||
namespace WatchIt.Website.Components.Common.ListComponent;
|
||||
|
||||
public partial class DatabasePageComponent<TItem, TQuery> : ComponentBase where TItem : IQueryOrderable<TItem> where TQuery : QueryParameters<TItem>
|
||||
public partial class ListComponent<TItem, TQuery> : ComponentBase where TItem : IQueryOrderable<TItem> where TQuery : QueryParameters<TItem>
|
||||
{
|
||||
#region SERVICES
|
||||
|
||||
@@ -23,6 +23,8 @@ public partial class DatabasePageComponent<TItem, TQuery> : ComponentBase where
|
||||
[Parameter] public required Func<TItem, string> NameSource { get; set; }
|
||||
[Parameter] public Func<TItem, string?> AdditionalNameInfoSource { get; set; } = _ => null;
|
||||
[Parameter] public required Func<TItem, RatingResponse> RatingSource { get; set; }
|
||||
[Parameter] public Func<TItem, short?>? SecondaryRatingSource { get; set; }
|
||||
[Parameter] public string? SecondaryRatingTitle { get; set; }
|
||||
[Parameter] public required string UrlIdTemplate { get; set; }
|
||||
[Parameter] public required Func<long, Action<Picture>, Task> PictureDownloadingTask { get; set; }
|
||||
[Parameter] public required Func<TQuery, Action<IEnumerable<TItem>>, Task> ItemDownloadingTask { get; set; }
|
||||
@@ -5,14 +5,18 @@
|
||||
<i id="star" class="fas fa-star"></i>
|
||||
}
|
||||
<div class="vstack">
|
||||
@if (Rating is not null && Rating.Count > 0)
|
||||
@if (SingleRating is not null)
|
||||
{
|
||||
<span id="ratingSingleLine">@($"{SingleRating}/10")</span>
|
||||
}
|
||||
else if (Rating is not null && Rating.Count > 0)
|
||||
{
|
||||
<span id="ratingAverage">@($"{Math.Round(Rating.Average, 2)}/10")</span>
|
||||
<span id="ratingCount">@(Rating.Count)</span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div id="ratingNoItems">
|
||||
<div id="ratingSingleLine">
|
||||
@if (Rating is null)
|
||||
{
|
||||
<span><div class="spinner-border spinner-border-sm"></div>/10</span>
|
||||
@@ -40,7 +44,7 @@
|
||||
font-size: @((1.3 * Scale).ToCultureInvariantString())rem;
|
||||
}
|
||||
|
||||
#ratingNoItems {
|
||||
#ratingSingleLine {
|
||||
font-size: @((1.3 * Scale).ToCultureInvariantString())rem;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ public partial class DisplayRatingComponent : ComponentBase
|
||||
#region PARAMETERS
|
||||
|
||||
[Parameter] public RatingResponse? Rating { get; set; }
|
||||
[Parameter] public short? SingleRating { get; set; }
|
||||
[Parameter] public DisplayRatingComponentEmptyMode EmptyMode { get; set; } = DisplayRatingComponentEmptyMode.NoRatings;
|
||||
[Parameter] public double Scale { get; set; } = 1;
|
||||
|
||||
|
||||
@@ -12,40 +12,66 @@
|
||||
<strong>@(Name)</strong>@(string.IsNullOrWhiteSpace(AdditionalInfo) ? string.Empty : AdditionalInfo)
|
||||
</a>
|
||||
</div>
|
||||
<div class="d-inline-flex gap-3">
|
||||
<a class="text-reset text-decoration-none" href="@(ItemUrl)">
|
||||
<div class="vstack gap-2">
|
||||
<span id="ratingNameText">Global rating:</span>
|
||||
<DisplayRatingComponent Rating="GlobalRating"
|
||||
EmptyMode="DisplayRatingComponent.DisplayRatingComponentEmptyMode.DoubleDash"
|
||||
Scale="0.85"/>
|
||||
</div>
|
||||
</a>
|
||||
@if (GetUserRatingMethod is not null && PutRatingMethod is not null && DeleteRatingMethod is not null)
|
||||
{
|
||||
<div class="vr"></div>
|
||||
<div class="vstack gap-2">
|
||||
<span id="ratingNameText">Your rating:</span>
|
||||
<div class="d-inline-flex align-items-center h-100">
|
||||
@if (_user is null)
|
||||
{
|
||||
<span id="ratingLoginInfoText">You must be logged in to rate</span>
|
||||
}
|
||||
else if (!_userRatingLoaded)
|
||||
{
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
|
||||
<span>Loading...</span>
|
||||
<table id="ratingTable" class="table table-transparent table-bordered align-middle m-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">
|
||||
<span class="rating-name-text">Global rating:</span>
|
||||
</th>
|
||||
@if (SecondaryRating is not null)
|
||||
{
|
||||
<th scope="col">
|
||||
<span class="rating-name-text">@(SecondaryRatingTitle):</span>
|
||||
</th>
|
||||
}
|
||||
@if (GetUserRatingMethod is not null && PutRatingMethod is not null && DeleteRatingMethod is not null)
|
||||
{
|
||||
<th class scope="col">
|
||||
<span class="rating-name-text">Your rating:</span>
|
||||
</th>
|
||||
}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<DisplayRatingComponent Rating="@(GlobalRating)"
|
||||
EmptyMode="DisplayRatingComponent.DisplayRatingComponentEmptyMode.DoubleDash"
|
||||
Scale="0.85"/>
|
||||
</td>
|
||||
@if (SecondaryRating is not null)
|
||||
{
|
||||
<td>
|
||||
<DisplayRatingComponent SingleRating="@(SecondaryRating)"
|
||||
EmptyMode="DisplayRatingComponent.DisplayRatingComponentEmptyMode.DoubleDash"
|
||||
Scale="0.85"/>
|
||||
</td>
|
||||
}
|
||||
@if (GetUserRatingMethod is not null && PutRatingMethod is not null && DeleteRatingMethod is not null)
|
||||
{
|
||||
<td>
|
||||
<div class="d-inline-flex align-items-center h-100">
|
||||
@if (_user is null)
|
||||
{
|
||||
<span id="ratingLoginInfoText">You must be logged in to rate</span>
|
||||
}
|
||||
else if (!_userRatingLoaded)
|
||||
{
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
|
||||
<span>Loading...</span>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<Rating Color="Color.Light" MaxValue="10" @bind-SelectedValue="@(_userRating)" @onclick="@(RatingChanged)"/>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<Rating Color="Color.Light" MaxValue="10" @bind-SelectedValue="@(_userRating)" @onclick="@(RatingChanged)"/>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</td>
|
||||
}
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -27,6 +27,8 @@ public partial class ListItemComponent : ComponentBase
|
||||
[Parameter] public required Func<Action<Picture>, Task> PosterDownloadingTask { get; set; }
|
||||
|
||||
[Parameter] public RatingResponse? GlobalRating { get; set; }
|
||||
[Parameter] public short? SecondaryRating { get; set; }
|
||||
[Parameter] public string? SecondaryRatingTitle { get; set; }
|
||||
[Parameter] public required Func<Action<RatingResponse>, Task> GetGlobalRatingMethod { get; set; }
|
||||
[Parameter] public Func<long, Action<short>, Action, Task>? GetUserRatingMethod { get; set; }
|
||||
[Parameter] public Func<RatingRequest, Task>? PutRatingMethod { get; set; }
|
||||
|
||||
@@ -1,10 +1,39 @@
|
||||
/* IDS */
|
||||
/* TAGS */
|
||||
|
||||
#ratingNameText {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
tbody, td, tfoot, th, thead, tr {
|
||||
border-color: inherit;
|
||||
border-style: unset;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* IDS */
|
||||
|
||||
#ratingLoginInfoText {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
#ratingTable {
|
||||
width: fit-content;
|
||||
border-spacing: unset;
|
||||
border-collapse: separate;
|
||||
margin-left: -0.5rem !important;
|
||||
}
|
||||
|
||||
#ratingTable > thead > tr > th:not(:last-child) {
|
||||
border-right: 1px solid #444;
|
||||
}
|
||||
|
||||
#ratingTable > tbody > tr > td:not(:last-child) {
|
||||
border-right: 1px solid #444;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* CLASSES */
|
||||
|
||||
.rating-name-text {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
@inherits FilterFormComponent<WatchIt.Common.Model.Movies.MovieResponse, WatchIt.Common.Model.Movies.MovieQueryParameters>
|
||||
@inherits WatchIt.Website.Components.Common.ListComponent.FilterFormComponent<WatchIt.Common.Model.Movies.MovieResponse, WatchIt.Common.Model.Movies.MovieQueryParameters>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@using WatchIt.Common.Model.Genders
|
||||
@inherits FilterFormComponent<WatchIt.Common.Model.Persons.PersonResponse, WatchIt.Common.Model.Persons.PersonQueryParameters>
|
||||
@inherits WatchIt.Website.Components.Common.ListComponent.FilterFormComponent<WatchIt.Common.Model.Persons.PersonResponse, WatchIt.Common.Model.Persons.PersonQueryParameters>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using WatchIt.Common.Model.Genders;
|
||||
using WatchIt.Common.Model.Persons;
|
||||
using WatchIt.Website.Components.Common.ListComponent;
|
||||
using WatchIt.Website.Services.Client.Genders;
|
||||
|
||||
namespace WatchIt.Website.Components.Pages.DatabasePage.Subcomponents;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@inherits FilterFormComponent<WatchIt.Common.Model.Series.SeriesResponse, WatchIt.Common.Model.Series.SeriesQueryParameters>
|
||||
@inherits WatchIt.Website.Components.Common.ListComponent.FilterFormComponent<WatchIt.Common.Model.Series.SeriesResponse, WatchIt.Common.Model.Series.SeriesQueryParameters>
|
||||
|
||||
<EditForm Model="@(Query)">
|
||||
<div class="container-grid">
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
@inherits WatchIt.Website.Components.Common.ListComponent.FilterFormComponent<WatchIt.Common.Model.Movies.MovieRatedResponse, WatchIt.Common.Model.Movies.MovieRatedQueryParameters>
|
||||
|
||||
|
||||
|
||||
<EditForm Model="@(Query)">
|
||||
<div class="container-grid">
|
||||
<div class="row mb-1">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="col-3 input-group-text">Title</span>
|
||||
<InputText class="col form-control" placeholder="Search with regex" @bind-Value="@(Query.Title)"></InputText>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-1">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="col-3 input-group-text">Original title</span>
|
||||
<InputText class="col form-control" placeholder="Search with regex" @bind-Value="@(Query.OriginalTitle)"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-1">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="col-3 input-group-text">Description</span>
|
||||
<InputText class="col form-control" placeholder="Search with regex" @bind-Value="@(Query.Description)"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-1">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="col-3 input-group-text">Release date</span>
|
||||
<InputDate TValue="DateOnly?" class="col form-control" @bind-Value="@(Query.ReleaseDateFrom)"/>
|
||||
<span class="col-auto input-group-text">-</span>
|
||||
<InputDate TValue="DateOnly?" class="col form-control" @bind-Value="@(Query.ReleaseDateTo)"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-1">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="col-3 input-group-text">Length</span>
|
||||
<NumericEdit TValue="short?" Class="col form-control" Min="0" @bind-Value="@(Query.LengthFrom)"/>
|
||||
<span class="col-auto input-group-text">-</span>
|
||||
<NumericEdit TValue="short?" Class="col form-control" Min="0" @bind-Value="@(Query.LengthTo)"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-1">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="col-3 input-group-text">Budget</span>
|
||||
<NumericEdit TValue="decimal?" Class="col form-control" Min="0" @bind-Value="@(Query.BudgetFrom)"/>
|
||||
<span class="col-auto input-group-text">-</span>
|
||||
<NumericEdit TValue="decimal?" Class="col form-control" Min="0" @bind-Value="@(Query.BudgetTo)"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-1">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="col-3 input-group-text">Rating (count)</span>
|
||||
<NumericEdit TValue="long?" Class="col form-control" Min="0" @bind-Value="@(Query.RatingCountFrom)"/>
|
||||
<span class="col-auto input-group-text">-</span>
|
||||
<NumericEdit TValue="long?" Class="col form-control" Min="0" @bind-Value="@(Query.RatingCountTo)"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-1">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="col-3 input-group-text">Rating (average)</span>
|
||||
<NumericEdit TValue="decimal?" Class="col form-control" Min="0" Max="10" Step="@(0.01M)" @bind-Value="@(Query.RatingAverageFrom)"/>
|
||||
<span class="col-auto input-group-text">-</span>
|
||||
<NumericEdit TValue="decimal?" Class="col form-control" Min="0" Max="10" Step="@(0.01M)" @bind-Value="@(Query.RatingAverageTo)"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-1">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="col-3 input-group-text">User rating</span>
|
||||
<NumericEdit TValue="decimal?" Class="col form-control" Min="0" Max="10" Step="1" @bind-Value="@(Query.UserRatingFrom)"/>
|
||||
<span class="col-auto input-group-text">-</span>
|
||||
<NumericEdit TValue="decimal?" Class="col form-control" Min="0" Max="10" Step="1" @bind-Value="@(Query.UserRatingTo)"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</EditForm>
|
||||
@@ -0,0 +1,77 @@
|
||||
@inherits WatchIt.Website.Components.Common.ListComponent.FilterFormComponent<WatchIt.Common.Model.Series.SeriesRatedResponse, WatchIt.Common.Model.Series.SeriesRatedQueryParameters>
|
||||
|
||||
<EditForm Model="@(Query)">
|
||||
<div class="container-grid">
|
||||
<div class="row mb-1">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="col-3 input-group-text">Title</span>
|
||||
<InputText class="col form-control" placeholder="Search with regex" @bind-Value="@(Query.Title)"></InputText>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-1">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="col-3 input-group-text">Original title</span>
|
||||
<InputText class="col form-control" placeholder="Search with regex" @bind-Value="@(Query.OriginalTitle)"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-1">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="col-3 input-group-text">Description</span>
|
||||
<InputText class="col form-control" placeholder="Search with regex" @bind-Value="@(Query.Description)"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-1">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="col-3 input-group-text">Release date</span>
|
||||
<InputDate TValue="DateOnly?" class="col form-control" @bind-Value="@(Query.ReleaseDateFrom)"/>
|
||||
<span class="col-auto input-group-text">-</span>
|
||||
<InputDate TValue="DateOnly?" class="col form-control" @bind-Value="@(Query.ReleaseDateTo)"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-1">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="col-3 input-group-text">Length</span>
|
||||
<NumericEdit TValue="short?" Class="col form-control" Min="0" @bind-Value="@(Query.LengthFrom)"/>
|
||||
<span class="col-auto input-group-text">-</span>
|
||||
<NumericEdit TValue="short?" Class="col form-control" Min="0" @bind-Value="@(Query.LengthTo)"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-1">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="col-3 input-group-text">Has ended</span>
|
||||
<div class="btn-group col">
|
||||
<input type="radio" class="btn-check" name="has_ended" id="has_ended_yes" autocomplete="off" @onclick="() => Query.HasEnded = true">
|
||||
<label class="btn btn-outline-secondary btn-sm" for="has_ended_yes">Yes</label>
|
||||
<input type="radio" class="btn-check" name="has_ended" id="has_ended_no_choice" autocomplete="off" @onclick="() => Query.HasEnded = null" checked>
|
||||
<label class="btn btn-outline-secondary btn-sm" for="has_ended_no_choice">No choice</label>
|
||||
<input type="radio" class="btn-check" name="has_ended" id="has_ended_no" autocomplete="off" @onclick="() => Query.HasEnded = false">
|
||||
<label class="btn btn-outline-secondary btn-sm" for="has_ended_no">No</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-1">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="col-3 input-group-text">Rating (count)</span>
|
||||
<NumericEdit TValue="long?" Class="col form-control" Min="0" @bind-Value="@(Query.RatingCountFrom)"/>
|
||||
<span class="col-auto input-group-text">-</span>
|
||||
<NumericEdit TValue="long?" Class="col form-control" Min="0" @bind-Value="@(Query.RatingCountTo)"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-1">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="col-3 input-group-text">Rating (average)</span>
|
||||
<NumericEdit TValue="decimal?" Class="col form-control" Min="0" Max="10" Step="@(0.01M)" @bind-Value="@(Query.RatingAverageFrom)"/>
|
||||
<span class="col-auto input-group-text">-</span>
|
||||
<NumericEdit TValue="decimal?" Class="col form-control" Min="0" Max="10" Step="@(0.01M)" @bind-Value="@(Query.RatingAverageTo)"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-1">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="col-3 input-group-text">User rating</span>
|
||||
<NumericEdit TValue="decimal?" Class="col form-control" Min="0" Max="10" Step="1" @bind-Value="@(Query.UserRatingFrom)"/>
|
||||
<span class="col-auto input-group-text">-</span>
|
||||
<NumericEdit TValue="decimal?" Class="col form-control" Min="0" Max="10" Step="1" @bind-Value="@(Query.UserRatingTo)"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</EditForm>
|
||||
@@ -79,7 +79,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="row pb-3">
|
||||
<div class="col">
|
||||
@Body
|
||||
</div>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
@using WatchIt.Common.Model.Series
|
||||
@using WatchIt.Website.Components.Pages.DatabasePage
|
||||
@using WatchIt.Website.Components.Pages.DatabasePage.Subcomponents
|
||||
@using WatchIt.Website.Components.Common.ListComponent
|
||||
|
||||
@page "/database/{type?}"
|
||||
|
||||
@@ -30,78 +31,78 @@
|
||||
@switch (Type)
|
||||
{
|
||||
case "movies":
|
||||
<DatabasePageComponent TItem="MovieResponse"
|
||||
TQuery="MovieQueryParameters"
|
||||
Title="Movies database"
|
||||
IdSource="@(item => item.Id)"
|
||||
NameSource="@(item => item.Title)"
|
||||
AdditionalNameInfoSource="@(item => item.ReleaseDate.HasValue ? $" ({item.ReleaseDate.Value.Year})" : null)"
|
||||
RatingSource="@(item => item.Rating)"
|
||||
UrlIdTemplate="/media/{0}"
|
||||
PictureDownloadingTask="@((id, action) => MediaClientService.GetMediaPoster(id, action))"
|
||||
ItemDownloadingTask="@(MoviesClientService.GetAllMovies)"
|
||||
SortingOptions="@(new Dictionary<string, string>
|
||||
{
|
||||
{ "rating.count", "Number of ratings" },
|
||||
{ "rating.average", "Average rating" },
|
||||
{ "title", "Title" },
|
||||
{ "release_date", "Release date" },
|
||||
})"
|
||||
PosterPlaceholder="/assets/media_poster.png"
|
||||
GetGlobalRatingMethod="@((id, action) => MediaClientService.GetMediaRating(id, action))"
|
||||
GetUserRatingMethod="@((id, userId, successAction, notfoundAction) => MediaClientService.GetMediaRatingByUser(id, userId, successAction, notfoundAction))"
|
||||
PutRatingMethod="@((id, request) => MediaClientService.PutMediaRating(id, request))"
|
||||
DeleteRatingMethod="@(id => MediaClientService.DeleteMediaRating(id))">
|
||||
<ListComponent TItem="MovieResponse"
|
||||
TQuery="MovieQueryParameters"
|
||||
Title="Movies database"
|
||||
IdSource="@(item => item.Id)"
|
||||
NameSource="@(item => item.Title)"
|
||||
AdditionalNameInfoSource="@(item => item.ReleaseDate.HasValue ? $" ({item.ReleaseDate.Value.Year})" : null)"
|
||||
RatingSource="@(item => item.Rating)"
|
||||
UrlIdTemplate="/media/{0}"
|
||||
PictureDownloadingTask="@((id, action) => MediaClientService.GetMediaPoster(id, action))"
|
||||
ItemDownloadingTask="@(MoviesClientService.GetAllMovies)"
|
||||
SortingOptions="@(new Dictionary<string, string>
|
||||
{
|
||||
{ "rating.count", "Number of ratings" },
|
||||
{ "rating.average", "Average rating" },
|
||||
{ "title", "Title" },
|
||||
{ "release_date", "Release date" },
|
||||
})"
|
||||
PosterPlaceholder="/assets/media_poster.png"
|
||||
GetGlobalRatingMethod="@((id, action) => MediaClientService.GetMediaRating(id, action))"
|
||||
GetUserRatingMethod="@((id, userId, successAction, notfoundAction) => MediaClientService.GetMediaRatingByUser(id, userId, successAction, notfoundAction))"
|
||||
PutRatingMethod="@((id, request) => MediaClientService.PutMediaRating(id, request))"
|
||||
DeleteRatingMethod="@(id => MediaClientService.DeleteMediaRating(id))">
|
||||
<MoviesFilterFormComponent/>
|
||||
</DatabasePageComponent>
|
||||
</ListComponent>
|
||||
break;
|
||||
case "series":
|
||||
<DatabasePageComponent TItem="SeriesResponse"
|
||||
TQuery="SeriesQueryParameters"
|
||||
Title="TV series database"
|
||||
IdSource="@(item => item.Id)"
|
||||
NameSource="@(item => item.Title)"
|
||||
AdditionalNameInfoSource="@(item => item.ReleaseDate.HasValue ? $" ({item.ReleaseDate.Value.Year})" : null)"
|
||||
RatingSource="@(item => item.Rating)"
|
||||
UrlIdTemplate="/media/{0}"
|
||||
PictureDownloadingTask="@((id, action) => MediaClientService.GetMediaPoster(id, action))"
|
||||
ItemDownloadingTask="@(SeriesClientService.GetAllSeries)"
|
||||
SortingOptions="@(new Dictionary<string, string>
|
||||
{
|
||||
{ "rating.count", "Number of ratings" },
|
||||
{ "rating.average", "Average rating" },
|
||||
{ "title", "Title" },
|
||||
{ "release_date", "Release date" },
|
||||
})"
|
||||
PosterPlaceholder="/assets/media_poster.png"
|
||||
GetGlobalRatingMethod="@((id, action) => MediaClientService.GetMediaRating(id, action))"
|
||||
GetUserRatingMethod="@((id, userId, successAction, notfoundAction) => MediaClientService.GetMediaRatingByUser(id, userId, successAction, notfoundAction))"
|
||||
PutRatingMethod="@((id, request) => MediaClientService.PutMediaRating(id, request))"
|
||||
DeleteRatingMethod="@(id => MediaClientService.DeleteMediaRating(id))">
|
||||
<ListComponent TItem="SeriesResponse"
|
||||
TQuery="SeriesQueryParameters"
|
||||
Title="TV series database"
|
||||
IdSource="@(item => item.Id)"
|
||||
NameSource="@(item => item.Title)"
|
||||
AdditionalNameInfoSource="@(item => item.ReleaseDate.HasValue ? $" ({item.ReleaseDate.Value.Year})" : null)"
|
||||
RatingSource="@(item => item.Rating)"
|
||||
UrlIdTemplate="/media/{0}"
|
||||
PictureDownloadingTask="@((id, action) => MediaClientService.GetMediaPoster(id, action))"
|
||||
ItemDownloadingTask="@(SeriesClientService.GetAllSeries)"
|
||||
SortingOptions="@(new Dictionary<string, string>
|
||||
{
|
||||
{ "rating.count", "Number of ratings" },
|
||||
{ "rating.average", "Average rating" },
|
||||
{ "title", "Title" },
|
||||
{ "release_date", "Release date" },
|
||||
})"
|
||||
PosterPlaceholder="/assets/media_poster.png"
|
||||
GetGlobalRatingMethod="@((id, action) => MediaClientService.GetMediaRating(id, action))"
|
||||
GetUserRatingMethod="@((id, userId, successAction, notfoundAction) => MediaClientService.GetMediaRatingByUser(id, userId, successAction, notfoundAction))"
|
||||
PutRatingMethod="@((id, request) => MediaClientService.PutMediaRating(id, request))"
|
||||
DeleteRatingMethod="@(id => MediaClientService.DeleteMediaRating(id))">
|
||||
<SeriesFilterFormComponent/>
|
||||
</DatabasePageComponent>
|
||||
</ListComponent>
|
||||
break;
|
||||
case "people":
|
||||
<DatabasePageComponent TItem="PersonResponse"
|
||||
TQuery="PersonQueryParameters"
|
||||
Title="People database"
|
||||
IdSource="@(item => item.Id)"
|
||||
NameSource="@(item => item.Name)"
|
||||
RatingSource="@(item => item.Rating)"
|
||||
UrlIdTemplate="/person/{0}"
|
||||
PictureDownloadingTask="@((id, action) => PersonsClientService.GetPersonPhoto(id, action))"
|
||||
ItemDownloadingTask="@(PersonsClientService.GetAllPersons)"
|
||||
SortingOptions="@(new Dictionary<string, string>
|
||||
{
|
||||
{ "rating.count", "Number of ratings" },
|
||||
{ "rating.average", "Average rating" },
|
||||
{ "name", "Name" },
|
||||
{ "birth_date", "Birth date" },
|
||||
{ "death_date", "Death date" },
|
||||
})"
|
||||
PosterPlaceholder="/assets/person_poster.png"
|
||||
GetGlobalRatingMethod="@((id, action) => PersonsClientService.GetPersonGlobalRating(id, action))">
|
||||
<ListComponent TItem="PersonResponse"
|
||||
TQuery="PersonQueryParameters"
|
||||
Title="People database"
|
||||
IdSource="@(item => item.Id)"
|
||||
NameSource="@(item => item.Name)"
|
||||
RatingSource="@(item => item.Rating)"
|
||||
UrlIdTemplate="/person/{0}"
|
||||
PictureDownloadingTask="@((id, action) => PersonsClientService.GetPersonPhoto(id, action))"
|
||||
ItemDownloadingTask="@(PersonsClientService.GetAllPersons)"
|
||||
SortingOptions="@(new Dictionary<string, string>
|
||||
{
|
||||
{ "rating.count", "Number of ratings" },
|
||||
{ "rating.average", "Average rating" },
|
||||
{ "name", "Name" },
|
||||
{ "birth_date", "Birth date" },
|
||||
{ "death_date", "Death date" },
|
||||
})"
|
||||
PosterPlaceholder="/assets/person_poster.png"
|
||||
GetGlobalRatingMethod="@((id, action) => PersonsClientService.GetPersonGlobalRating(id, action))">
|
||||
<PersonsFilterFormComponent/>
|
||||
</DatabasePageComponent>
|
||||
</ListComponent>
|
||||
break;
|
||||
}
|
||||
@@ -1,5 +1,9 @@
|
||||
@using System.Text
|
||||
@using WatchIt.Common.Model.Movies
|
||||
@using WatchIt.Common.Model.Series
|
||||
@using WatchIt.Website.Components.Pages.UserPage.Panels
|
||||
@using WatchIt.Website.Components.Common.ListComponent
|
||||
@using WatchIt.Website.Components.Pages.UserPage.Subcomponents
|
||||
|
||||
@page "/user/{id:long?}"
|
||||
|
||||
@@ -56,17 +60,59 @@
|
||||
<Tab Name="movies">Movies</Tab>
|
||||
<Tab Name="series">TV Series</Tab>
|
||||
<Tab Name="people">People</Tab>
|
||||
<Tab Name="people">Roles</Tab>
|
||||
<Tab Name="roles">Roles</Tab>
|
||||
</Items>
|
||||
<Content>
|
||||
<TabPanel Name="summary">
|
||||
|
||||
</TabPanel>
|
||||
<TabPanel Name="movies">
|
||||
|
||||
<div class="mt-default">
|
||||
<ListComponent TItem="MovieRatedResponse"
|
||||
TQuery="MovieRatedQueryParameters"
|
||||
Title="Rated movies"
|
||||
IdSource="@(item => item.Id)"
|
||||
NameSource="@(item => item.Title)"
|
||||
AdditionalNameInfoSource="@(item => item.ReleaseDate.HasValue ? $" ({item.ReleaseDate.Value.Year})" : null)"
|
||||
RatingSource="@(item => item.Rating)"
|
||||
SecondaryRatingSource="@(item => _owner ? null : item.UserRating)"
|
||||
SecondaryRatingTitle="User rating"
|
||||
UrlIdTemplate="/media/{0}"
|
||||
PictureDownloadingTask="@((id, action) => MediaClientService.GetMediaPoster(id, action))"
|
||||
ItemDownloadingTask="@((query, action) => AccountsClientService.GetAccountRatedMovies(Id!.Value, query, action))"
|
||||
SortingOptions="@(new Dictionary<string, string> { { "user_rating", "User rating" }, { "rating.count", "Number of ratings" }, { "rating.average", "Average rating" }, { "title", "Title" }, { "release_date", "Release date" } })"
|
||||
PosterPlaceholder="/assets/media_poster.png"
|
||||
GetGlobalRatingMethod="@((id, action) => MediaClientService.GetMediaRating(id, action))"
|
||||
GetUserRatingMethod="@((id, userId, successAction, notfoundAction) => MediaClientService.GetMediaRatingByUser(id, userId, successAction, notfoundAction))"
|
||||
PutRatingMethod="@((id, request) => MediaClientService.PutMediaRating(id, request))"
|
||||
DeleteRatingMethod="@(id => MediaClientService.DeleteMediaRating(id))">
|
||||
<MoviesRatedFilterFormComponent/>
|
||||
</ListComponent>
|
||||
</div>
|
||||
</TabPanel>
|
||||
<TabPanel Name="series">
|
||||
|
||||
<div class="mt-default">
|
||||
<ListComponent TItem="SeriesRatedResponse"
|
||||
TQuery="SeriesRatedQueryParameters"
|
||||
Title="Rated TV series"
|
||||
IdSource="@(item => item.Id)"
|
||||
NameSource="@(item => item.Title)"
|
||||
AdditionalNameInfoSource="@(item => item.ReleaseDate.HasValue ? $" ({item.ReleaseDate.Value.Year})" : null)"
|
||||
RatingSource="@(item => item.Rating)"
|
||||
SecondaryRatingSource="@(item => _owner ? null : item.UserRating)"
|
||||
SecondaryRatingTitle="User rating"
|
||||
UrlIdTemplate="/media/{0}"
|
||||
PictureDownloadingTask="@((id, action) => MediaClientService.GetMediaPoster(id, action))"
|
||||
ItemDownloadingTask="@((query, action) => AccountsClientService.GetAccountRatedSeries(Id!.Value, query, action))"
|
||||
SortingOptions="@(new Dictionary<string, string> { { "user_rating", "User rating" }, { "rating.count", "Number of ratings" }, { "rating.average", "Average rating" }, { "title", "Title" }, { "release_date", "Release date" } })"
|
||||
PosterPlaceholder="/assets/media_poster.png"
|
||||
GetGlobalRatingMethod="@((id, action) => MediaClientService.GetMediaRating(id, action))"
|
||||
GetUserRatingMethod="@((id, userId, successAction, notfoundAction) => MediaClientService.GetMediaRatingByUser(id, userId, successAction, notfoundAction))"
|
||||
PutRatingMethod="@((id, request) => MediaClientService.PutMediaRating(id, request))"
|
||||
DeleteRatingMethod="@(id => MediaClientService.DeleteMediaRating(id))">
|
||||
<SeriesRatedFilterFormComponent/>
|
||||
</ListComponent>
|
||||
</div>
|
||||
</TabPanel>
|
||||
<TabPanel Name="people">
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ using WatchIt.Common.Model.Accounts;
|
||||
using WatchIt.Website.Layout;
|
||||
using WatchIt.Website.Services.Authentication;
|
||||
using WatchIt.Website.Services.Client.Accounts;
|
||||
using WatchIt.Website.Services.Client.Media;
|
||||
|
||||
namespace WatchIt.Website.Pages;
|
||||
|
||||
@@ -13,6 +14,7 @@ public partial class UserPage : ComponentBase
|
||||
[Inject] private NavigationManager NavigationManager { get; set; } = default!;
|
||||
[Inject] private IAuthenticationService AuthenticationService { get; set; } = default!;
|
||||
[Inject] private IAccountsClientService AccountsClientService { get; set; } = default!;
|
||||
[Inject] private IMediaClientService MediaClientService { get; set; } = default!;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -78,7 +80,7 @@ public partial class UserPage : ComponentBase
|
||||
Id = user.Id;
|
||||
}
|
||||
|
||||
await AccountsClientService.GetAccountInfoById(Id.Value, data => _accountData = data);
|
||||
await AccountsClientService.GetAccountInfo(Id.Value, data => _accountData = data);
|
||||
_owner = Id.Value == user?.Id;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,9 +22,10 @@
|
||||
"AuthenticateRefresh": "/authenticate-refresh",
|
||||
"Logout": "/logout",
|
||||
"GetProfilePicture": "/{0}/profile-picture",
|
||||
"GetAccountInfoById": "/{0}/info",
|
||||
"GetAccountInfo": "/info",
|
||||
"PutAccountInfo": "/info"
|
||||
"GetAccountInfo": "/{0}/info",
|
||||
"PutAccountInfo": "/info",
|
||||
"GetAccountRatedMovies": "/{0}/movies",
|
||||
"GetAccountRatedSeries": "/{0}/series"
|
||||
},
|
||||
"Genders": {
|
||||
"Base": "/genders",
|
||||
|
||||
Reference in New Issue
Block a user