395 lines
13 KiB
Plaintext
395 lines
13 KiB
Plaintext
@page "/circles"
|
|
@using JSMR.Application.Circles.Queries.Search
|
|
@using JSMR.Application.Common.Search
|
|
@using JSMR.UI.Blazor.Components
|
|
@using JSMR.UI.Blazor.Services
|
|
@inject VoiceWorksClient Client
|
|
@inject IJSRuntime JS
|
|
@inject HttpClient Http
|
|
|
|
<PageTitle>Circles</PageTitle>
|
|
|
|
<h1>Circles</h1>
|
|
|
|
<div class="search-filter-control-container">
|
|
<div class="search-filter-control-span-3">
|
|
<MudTextField @bind-Value="Keywords" Placeholder="Circle Name or Maker Id" Immediate="true" DebounceInterval="500" Variant="Variant.Outlined" Margin="Margin.Dense" Adornment="@Adornment.End" AdornmentIcon="@Icons.Material.Outlined.Search" />
|
|
</div>
|
|
<div class="search-filter-control-span-1">
|
|
<MudSelect @bind-Value="SelectedCircleStatus" Placeholder="Circle Status" Dense="true" Variant="Variant.Outlined" Margin="Margin.Dense">
|
|
<MudSelectItem Value="@CircleStatus.NotBlacklisted.ToString()">Not Blacklisted</MudSelectItem>
|
|
<MudSelectItem Value="@CircleStatus.Favorited.ToString()">Favorite</MudSelectItem>
|
|
<MudSelectItem Value="@CircleStatus.Blacklisted.ToString()">Blacklisted</MudSelectItem>
|
|
<MudSelectItem Value="@CircleStatus.Spam.ToString()">Spam</MudSelectItem>
|
|
<MudSelectItem Value="@String.Empty">All</MudSelectItem>
|
|
</MudSelect>
|
|
</div>
|
|
</div>
|
|
|
|
@if (searchResults is null)
|
|
{
|
|
<p>Loading…</p>
|
|
}
|
|
else if (searchResults.Items.Length == 0)
|
|
{
|
|
<p>No results.</p>
|
|
}
|
|
else
|
|
{
|
|
<div class="circle-item-container-2">
|
|
@foreach (var item in searchResults.Items)
|
|
{
|
|
<div class="circle-item">
|
|
@* <JImage @key="item.CircleId" ContainerClass="j-circle-image-container" ImageClass="j-circle-image" Source="@ImageUrlProvider.GetImageURL(item.LatestProductId, item.LatestVoiceWorkHasImage ?? false, item.LatestVoiceWorkSalesDate, "main")" /> *@
|
|
<div class="fdfs">
|
|
<div class="circle-name">@item.Name</div>
|
|
<div>@item.MakerId</div>
|
|
</div>
|
|
@if (item.Favorite)
|
|
{
|
|
<MudChip T="string" Label="true" Color="Color.Info" Style="width: 100%" Variant="Variant.Outlined">Favorite</MudChip>
|
|
}
|
|
else if (item.Blacklisted)
|
|
{
|
|
<MudChip T="string" Label="true" Color="Color.Warning" Style="width: 100%" Variant="Variant.Outlined">Blacklisted</MudChip>
|
|
}
|
|
else if (item.Spam)
|
|
{
|
|
<MudChip T="string" Label="true" Color="Color.Error" Style="width: 100%" Variant="Variant.Outlined">Spam</MudChip>
|
|
}
|
|
else
|
|
{
|
|
<MudChip T="string" Label="true" Style="width: 100%" Variant="Variant.Outlined">Normal</MudChip>
|
|
}
|
|
|
|
<div class="circle-star-container">
|
|
@if (item.Releases > 0)
|
|
{
|
|
<div class="circle-star @GetStarRatingClass(item)"></div>
|
|
}
|
|
</div>
|
|
|
|
<div class="icon-text">
|
|
<MudIcon Icon="@Icons.Material.Outlined.Headphones" />
|
|
<span>@item.Releases</span>
|
|
@if (item.Pending > 0)
|
|
{
|
|
<span>/</span>
|
|
<span style="color: #ffa462">@item.Pending</span>
|
|
}
|
|
</div>
|
|
|
|
<div class="icon-text">
|
|
<MudIcon Icon="@Icons.Material.Outlined.ArrowCircleDown" />
|
|
<span>@item.Downloads.ToString("n0")</span>
|
|
</div>
|
|
|
|
</div>
|
|
}
|
|
</div>
|
|
|
|
<MudDataGrid Items="@searchResults.Items" Style="table-layout: fixed">
|
|
<Columns>
|
|
<TemplateColumn HeaderStyle="width: 12em">
|
|
<CellTemplate>
|
|
<JImage ContainerClass="j-circle-image-container-mini" ImageClass="j-circle-image-mini" Source="@ImageUrlProvider.GetImageURL(context.Item.LatestProductId, context.Item.LatestVoiceWorkHasImage ?? false, context.Item.LatestVoiceWorkSalesDate, "main")" />
|
|
</CellTemplate>
|
|
</TemplateColumn>
|
|
<TemplateColumn Title="Name">
|
|
<CellTemplate>
|
|
<div class="circle-name-container">
|
|
<div class="circle-name">@context.Item.Name</div>
|
|
</div>
|
|
</CellTemplate>
|
|
</TemplateColumn>
|
|
@* <TemplateColumn Title="Maker Id">
|
|
<CellTemplate>
|
|
<MudChip T="string" Label="true" Class="maker-id">@context.Item.MakerId</MudChip>
|
|
</CellTemplate>
|
|
</TemplateColumn> *@
|
|
@* <PropertyColumn Property="x => x.Name" Title="Name" />
|
|
<PropertyColumn Property="x => x.MakerId" Title="Maker Id" HeaderStyle="width: 12em" /> *@
|
|
<TemplateColumn Title="Status" HeaderStyle="width: 10em">
|
|
<CellTemplate>
|
|
@if (context.Item.Favorite)
|
|
{
|
|
<MudChip T="string" Label="true" Color="Color.Info" Style="width: 100%">Favorite</MudChip>
|
|
}
|
|
else if (context.Item.Blacklisted)
|
|
{
|
|
<MudChip T="string" Label="true" Color="Color.Warning" Style="color:black; width: 100%">Blacklisted</MudChip>
|
|
}
|
|
else if (context.Item.Spam)
|
|
{
|
|
<MudChip T="string" Label="true" Color="Color.Error" Style="width: 100%">Spam</MudChip>
|
|
}
|
|
else
|
|
{
|
|
<MudChip T="string" Label="true" Style="width: 100%">Normal</MudChip>
|
|
}
|
|
</CellTemplate>
|
|
</TemplateColumn>
|
|
<TemplateColumn Title="Rating" HeaderStyle="width: 8em">
|
|
<CellTemplate>
|
|
@if (context.Item.Releases > 0)
|
|
{
|
|
<div class="circle-star-container">
|
|
<div class="circle-star @GetStarRatingClass(context.Item)"></div>
|
|
</div>
|
|
}
|
|
</CellTemplate>
|
|
</TemplateColumn>
|
|
<PropertyColumn Property="x => x.Downloads" Title="Downloads" HeaderStyle="width: 12em" />
|
|
<PropertyColumn Property="x => x.Releases" Title="Releases" HeaderStyle="width: 12em" />
|
|
<PropertyColumn Property="x => x.Pending" Title="Pending" HeaderStyle="width: 12em" />
|
|
@* <TemplateColumn Title="First Release Date" HeaderStyle="width: 14em">
|
|
<CellTemplate>
|
|
<MudText>@context.Item.FirstReleaseDate?.ToString("MMMM d, yyyy")</MudText>
|
|
</CellTemplate>
|
|
</TemplateColumn>
|
|
<TemplateColumn Title="Latest Release Date" HeaderStyle="width: 14em">
|
|
<CellTemplate>
|
|
<MudText>@context.Item.LatestReleaseDate?.ToString("MMMM d, yyyy")</MudText>
|
|
</CellTemplate>
|
|
</TemplateColumn> *@
|
|
</Columns>
|
|
</MudDataGrid>
|
|
|
|
@* <div class="items-container circle-items-container">
|
|
@foreach (var item in searchResults.Items)
|
|
{
|
|
<MudPaper Outlined="true">
|
|
<JImage @key="item.CircleId" ContainerClass="j-circle-image-container" ImageClass="j-circle-image" Source="@ImageUrlProvider.GetImageURL(item.LatestProductId, item.LatestVoiceWorkHasImage ?? false, item.LatestVoiceWorkSalesDate, "main")" />
|
|
<MudText Typo="Typo.h6">@item.Name</MudText>
|
|
<div>@item.Releases</div>
|
|
<div>@item.Pending</div>
|
|
|
|
@if (item.Releases > 0)
|
|
{
|
|
<div class="circle-star-container">
|
|
<div class="circle-star @GetStarRatingClass(item)"></div>
|
|
</div>
|
|
}
|
|
|
|
<div>@item.Downloads</div>
|
|
<MudChip T="string" Variant="Variant.Outlined" Icon="@Icons.Material.Filled.Download" Color="Color.Info">@item.Downloads.ToString("n0")</MudChip>
|
|
<div>@item.FirstReleaseDate?.ToString("MMMM d, yyyy")</div>
|
|
<div>@item.LatestReleaseDate?.ToString("MMMM d, yyyy")</div>
|
|
<MudIconButton Size="@Size.Small" Icon="@Icons.Material.Filled.Favorite" Color="@(item.Favorite? Color.Secondary: Color.Dark)" />
|
|
<MudIconButton Size="@Size.Small" Icon="@Icons.Material.Filled.Block" Color="@(item.Blacklisted? Color.Secondary: Color.Dark)" />
|
|
<MudIconButton Size="@Size.Small" Icon="@Icons.Material.Filled.RestoreFromTrash" Color="@(item.Spam? Color.Secondary: Color.Dark)" />
|
|
</MudPaper>
|
|
}
|
|
</div> *@
|
|
|
|
<JPagination @bind-PageNumber="PageNumber" @bind-PageSize="PageSize" @bind-TotalItems="searchResults.TotalItems" />
|
|
}
|
|
|
|
<style>
|
|
.circle-item-container-2 {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 1.5em;
|
|
}
|
|
|
|
.circle-item {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 1rem;
|
|
border-width: 2px;
|
|
border-top-color: #353B4C;
|
|
border-left-color: #212630;
|
|
border-right-color: #212531;
|
|
border-bottom-color: #212530;
|
|
border-radius: 30px;
|
|
background-image: linear-gradient(0deg, #1C2029, #1C1F28);
|
|
display: grid;
|
|
grid-template-columns: 1fr 100px 100px 100px 100px;
|
|
grid-column-gap: 2rem;
|
|
}
|
|
|
|
.circle-name {
|
|
color: #d2dce6;
|
|
font-size: 1.5rem;
|
|
font-weight: 500;
|
|
font-family: "M+ 1p";
|
|
}
|
|
|
|
.icon-text {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: .5rem;
|
|
font-size: 1rem;
|
|
}
|
|
|
|
.icon-text > .mud-icon-root.mud-svg-icon {
|
|
fill: #737890;
|
|
}
|
|
|
|
.mud-table-root {
|
|
table-layout: fixed;
|
|
}
|
|
|
|
.j-pager {
|
|
position: fixed;
|
|
bottom: 0;
|
|
left: 0;
|
|
right: 0;
|
|
justify-content: center;
|
|
z-index: 2;
|
|
background: var(--mud-palette-background);
|
|
padding: .5em 1em;
|
|
}
|
|
|
|
.circle-name-container {
|
|
display: inline-flex;
|
|
flex-direction: column;
|
|
gap: .5rem;
|
|
}
|
|
|
|
.circle-name {
|
|
font-size: 1.2rem;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.maker-id {
|
|
margin: 0;
|
|
}
|
|
</style>
|
|
|
|
@code {
|
|
private string? keywords;
|
|
|
|
public string? Keywords
|
|
{
|
|
get { return keywords; }
|
|
set
|
|
{
|
|
keywords = value;
|
|
_ = UpdateDataAsync(true);
|
|
}
|
|
}
|
|
|
|
private string circleStatus = string.Empty;
|
|
|
|
public string SelectedCircleStatus
|
|
{
|
|
get { return circleStatus; }
|
|
set
|
|
{
|
|
circleStatus = value;
|
|
_ = UpdateDataAsync(true);
|
|
}
|
|
}
|
|
|
|
private int pageNumber = 1;
|
|
|
|
public int PageNumber
|
|
{
|
|
get { return pageNumber; }
|
|
set
|
|
{
|
|
pageNumber = value;
|
|
_ = UpdateDataAsync(false);
|
|
}
|
|
}
|
|
|
|
int pageSize = 100;
|
|
|
|
public int PageSize
|
|
{
|
|
get { return pageSize; }
|
|
set
|
|
{
|
|
pageSize = value;
|
|
_ = UpdateDataAsync(true);
|
|
}
|
|
}
|
|
|
|
SearchResult<CircleSearchItem>? searchResults;
|
|
|
|
protected override Task OnInitializedAsync()
|
|
{
|
|
_ = LoadCirclesAsync();
|
|
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
private async Task LoadCirclesAsync()
|
|
{
|
|
SearchCirclesRequest request = new(
|
|
Options: new()
|
|
{
|
|
PageNumber = PageNumber,
|
|
PageSize = pageSize,
|
|
Criteria = new()
|
|
{
|
|
Name = Keywords,
|
|
Status = string.IsNullOrWhiteSpace(SelectedCircleStatus) == false ? Enum.Parse<CircleStatus>(SelectedCircleStatus) : null
|
|
},
|
|
SortOptions =
|
|
[
|
|
new(CircleSortField.Name, Application.Common.Search.SortDirection.Ascending)
|
|
]
|
|
}
|
|
);
|
|
|
|
await JS.InvokeVoidAsync("pageHelpers.scrollToTop");
|
|
var result = await Client.SearchAsync(request);
|
|
|
|
searchResults = result?.Results ?? new();
|
|
|
|
await InvokeAsync(StateHasChanged);
|
|
}
|
|
|
|
private async Task UpdateDataAsync(bool resetPageNumber)
|
|
{
|
|
if (resetPageNumber)
|
|
pageNumber = 1;
|
|
|
|
await LoadCirclesAsync();
|
|
}
|
|
|
|
private string GetStarRatingClass(CircleSearchItem item)
|
|
{
|
|
double averageDownloads = item.Downloads / item.Releases;
|
|
|
|
if (averageDownloads < 100)
|
|
{
|
|
return "circle-star-poor";
|
|
}
|
|
|
|
if (averageDownloads < 250)
|
|
{
|
|
return "circle-star-below-average";
|
|
}
|
|
|
|
if (averageDownloads < 500)
|
|
{
|
|
return "circle-star-average";
|
|
}
|
|
|
|
if (averageDownloads < 1000)
|
|
{
|
|
return "circle-star-above-average";
|
|
}
|
|
|
|
if (averageDownloads < 2000)
|
|
{
|
|
return "circle-star-popular";
|
|
}
|
|
|
|
if (averageDownloads < 4000)
|
|
{
|
|
return "circle-star-super-popular";
|
|
}
|
|
|
|
if (averageDownloads < 8000)
|
|
{
|
|
return "circle-star-ultra-popular";
|
|
}
|
|
|
|
return "circle-star-god-tier";
|
|
}
|
|
}
|