people database page created

This commit is contained in:
2024-10-21 21:44:24 +02:00
Unverified
parent 4584287779
commit 9c4c51cbfb
6 changed files with 225 additions and 85 deletions

View File

@@ -48,29 +48,40 @@
{
if (string.IsNullOrWhiteSpace(_error))
{
foreach (TItem item in _items)
if (_items.Count > 0)
{
<div role="button" class="rounded-3 panel panel-regular p-2" @onclick="@(() => NavigationManager.NavigateTo(string.Format(UrlIdTemplate, IdSource(item))))">
<ListItemComponent Id="@(IdSource(item))"
Name="@(NameSource(item))"
AdditionalNameInfo="@(AdditionalNameInfoSource(item))"
Rating="@(RatingSource(item))"
PictureDownloadingTask="@(PictureDownloadingTask)"/>
</div>
foreach (TItem item in _items)
{
<div role="button" class="rounded-3 panel panel-regular p-2" @onclick="@(() => NavigationManager.NavigateTo(string.Format(UrlIdTemplate, IdSource(item))))">
<ListItemComponent Id="@(IdSource(item))"
Name="@(NameSource(item))"
AdditionalNameInfo="@(AdditionalNameInfoSource(item))"
Rating="@(RatingSource(item))"
PictureDownloadingTask="@(PictureDownloadingTask)"/>
</div>
}
if (!_allItemsLoaded)
{
<div role="button" class="rounded-3 panel panel-regular p-3" @onclick="DownloadItems">
<div class="d-flex justify-content-center">
@if (!_itemsLoading)
{
<strong>Load more</strong>
}
else
{
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
<strong>Loading...</strong>
}
</div>
</div>
}
}
if (!_allItemsLoaded)
else
{
<div role="button" class="rounded-3 panel panel-regular p-3" @onclick="DownloadItems">
<div class="panel">
<div class="d-flex justify-content-center">
@if (!_itemsLoading)
{
<strong>Load more</strong>
}
else
{
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
<strong>Loading...</strong>
}
<span>No items found</span>
</div>
</div>
}

View File

@@ -0,0 +1,71 @@
@using WatchIt.Common.Model.Genders
@inherits FilterFormComponent<WatchIt.Common.Model.Persons.PersonResponse, WatchIt.Common.Model.Persons.PersonQueryParameters>
<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">Name</span>
<InputText class="col form-control" placeholder="Search with regex" @bind-Value="@(Query.Name)"></InputText>
</div>
</div>
<div class="row my-1">
<div class="input-group input-group-sm">
<span class="col-3 input-group-text">Full name</span>
<InputText class="col form-control" placeholder="Search with regex" @bind-Value="@(Query.FullName)"/>
</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">Birth date</span>
<InputDate TValue="DateOnly?" class="col form-control" @bind-Value="@(Query.BirthDateFrom)"/>
<span class="col-auto input-group-text">-</span>
<InputDate TValue="DateOnly?" class="col form-control" @bind-Value="@(Query.BirthDateTo)"/>
</div>
</div>
<div class="row my-1">
<div class="input-group input-group-sm">
<span class="col-3 input-group-text">Death date</span>
<InputDate TValue="DateOnly?" class="col form-control" @bind-Value="@(Query.DeathDateFrom)"/>
<span class="col-auto input-group-text">-</span>
<InputDate TValue="DateOnly?" class="col form-control" @bind-Value="@(Query.DeathDateTo)"/>
</div>
</div>
<div class="row my-1">
<div class="input-group input-group-sm">
<span class="col-3 input-group-text">Gender</span>
<InputSelect TValue="short?" class="col form-control" @bind-Value="@(Query.GenderId)">
<option @onclick="() => Query.GenderId = null">No choice</option>
@foreach (GenderResponse gender in _genders)
{
<option value="@(gender.Id)">@(gender.Name)</option>
}
</InputSelect>
</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>
</EditForm>

View File

@@ -0,0 +1,48 @@
using Microsoft.AspNetCore.Components;
using WatchIt.Common.Model.Genders;
using WatchIt.Common.Model.Persons;
using WatchIt.Website.Services.WebAPI.Genders;
namespace WatchIt.Website.Components.Pages.DatabasePage.Subcomponents;
public partial class PersonsFilterFormComponent : FilterFormComponent<PersonResponse, PersonQueryParameters>
{
#region SERVICES
[Inject] private IGendersWebAPIService GendersWebAPIService { get; set; } = default!;
#endregion
#region FIELDS
private IEnumerable<GenderResponse> _genders = [];
#endregion
#region PRIVATE METHODS
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
List<Task> endTasks = new List<Task>();
// STEP 0
endTasks.AddRange(
[
GendersWebAPIService.GetAllGenders(successAction: data => _genders = data)
]);
// END
await Task.WhenAll(endTasks);
StateHasChanged();
}
}
#endregion
}

View File

@@ -37,6 +37,7 @@
<DropdownMenu>
<DropdownItem Clicked="@(() => NavigationManager.NavigateTo("/database/movies"))">Movies</DropdownItem>
<DropdownItem Clicked="@(() => NavigationManager.NavigateTo("/database/series"))">TV Series</DropdownItem>
<DropdownItem Clicked="@(() => NavigationManager.NavigateTo("/database/people"))">People</DropdownItem>
</DropdownMenu>
</Dropdown>
<button type="button" class="btn btn-sm" @onclick="@(() => _searchbarVisible = true)">⌕</button>

View File

@@ -1,4 +1,5 @@
@using WatchIt.Common.Model.Movies
@using WatchIt.Common.Model.Persons
@using WatchIt.Common.Model.Series
@using WatchIt.Website.Components.Pages.DatabasePage
@using WatchIt.Website.Components.Pages.DatabasePage.Subcomponents
@@ -17,63 +18,78 @@
case "series":
@("Series");
break;
case "people":
@("People");
break;
}
@(" database")
</PageTitle>
@if (_loaded)
@switch (Type)
{
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) => MediaWebAPIService.GetMediaPoster(id, action))"
ItemDownloadingTask="@(MoviesWebAPIService.GetAllMovies)"
SortingOptions="@(new Dictionary<string, string>
{
{ "rating.count", "Number of ratings" },
{ "rating.average", "Average rating" },
{ "title", "Title" },
{ "release_date", "Release date" },
})">
<MoviesFilterFormComponent/>
</DatabasePageComponent>
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) => MediaWebAPIService.GetMediaPoster(id, action))"
ItemDownloadingTask="@(SeriesWebAPIService.GetAllSeries)"
SortingOptions="@(new Dictionary<string, string>
{
{ "rating.count", "Number of ratings" },
{ "rating.average", "Average rating" },
{ "title", "Title" },
{ "release_date", "Release date" },
})">
<SeriesFilterFormComponent/>
</DatabasePageComponent>
break;
}
}
else
{
<div class="m-5">
<LoadingComponent/>
</div>
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) => MediaWebAPIService.GetMediaPoster(id, action))"
ItemDownloadingTask="@(MoviesWebAPIService.GetAllMovies)"
SortingOptions="@(new Dictionary<string, string>
{
{ "rating.count", "Number of ratings" },
{ "rating.average", "Average rating" },
{ "title", "Title" },
{ "release_date", "Release date" },
})">
<MoviesFilterFormComponent/>
</DatabasePageComponent>
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) => MediaWebAPIService.GetMediaPoster(id, action))"
ItemDownloadingTask="@(SeriesWebAPIService.GetAllSeries)"
SortingOptions="@(new Dictionary<string, string>
{
{ "rating.count", "Number of ratings" },
{ "rating.average", "Average rating" },
{ "title", "Title" },
{ "release_date", "Release date" },
})">
<SeriesFilterFormComponent/>
</DatabasePageComponent>
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) => PersonsWebAPIService.GetPersonPhoto(id, action))"
ItemDownloadingTask="@(PersonsWebAPIService.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" },
})">
<PersonsFilterFormComponent/>
</DatabasePageComponent>
break;
}

View File

@@ -1,6 +1,7 @@
using Microsoft.AspNetCore.Components;
using WatchIt.Website.Services.WebAPI.Media;
using WatchIt.Website.Services.WebAPI.Movies;
using WatchIt.Website.Services.WebAPI.Persons;
using WatchIt.Website.Services.WebAPI.Series;
namespace WatchIt.Website.Pages;
@@ -13,6 +14,7 @@ public partial class DatabasePage : ComponentBase
[Inject] private IMediaWebAPIService MediaWebAPIService { get; set; } = default!;
[Inject] private IMoviesWebAPIService MoviesWebAPIService { get; set; } = default!;
[Inject] private ISeriesWebAPIService SeriesWebAPIService { get; set; } = default!;
[Inject] private IPersonsWebAPIService PersonsWebAPIService { get; set; } = default!;
#endregion
@@ -28,9 +30,7 @@ public partial class DatabasePage : ComponentBase
#region FIELDS
private static IEnumerable<string> _databaseTypes = ["movies", "series"];
private bool _loaded;
private static IEnumerable<string> _databaseTypes = ["movies", "series", "people"];
#endregion
@@ -38,18 +38,11 @@ public partial class DatabasePage : ComponentBase
#region PRIVATE METHODS
protected override async Task OnAfterRenderAsync(bool firstRender)
protected override void OnParametersSet()
{
if (firstRender)
if (!_databaseTypes.Contains(Type))
{
// INIT
if (!_databaseTypes.Contains(Type))
{
NavigationManager.NavigateTo($"/database/{_databaseTypes.First()}");
}
_loaded = true;
StateHasChanged();
NavigationManager.NavigateTo($"/database/{_databaseTypes.First()}");
}
}