Updated UI with BitBlazor components.

This commit is contained in:
2025-11-22 14:42:29 -05:00
parent 2418bd0a8f
commit 8490b49354
22 changed files with 552 additions and 68 deletions

View File

@@ -4,7 +4,7 @@
</div>
<MudPagination class="pager" ShowFirstButton="true" ShowLastButton="true" Count="@((int)Math.Ceiling((decimal)TotalItems / (decimal)PageSize))" Selected="@PageNumber" SelectedChanged="OnSelectedChanged" />
<div class="page-sizes">
<MudSelect T="int" Value="PageSize" ValueChanged="OnPageSizeChanged" Dense="true" Variant="Variant.Outlined" Margin="Margin.Dense">
<MudSelect T="int" Value="PageSize" ValueChanged="OnPageSizeChanged" Dense="true" Variant="MudBlazor.Variant.Outlined" Margin="Margin.Dense">
@foreach (int value in PageSizes)
{
<MudSelectItem Value="@value">@value</MudSelectItem>

View File

@@ -1,8 +1,9 @@
@using JSMR.Application.VoiceWorks.Queries.Search
@using JSMR.Domain.Enums
@using JSMR.UI.Blazor.Services
@using System.Globalization
<div class="j-card j-voice-work-card">
<div class=@GetCardClasses(Product)>
<div class="j-voice-work-image-container">
<JImage OverlayClass="j-voice-work-image-overlay" ImageClass="j-voice-work-image" Source="@ImageUrlProvider.GetImageUrl(Product, "main")"></JImage>
</div>
@@ -15,14 +16,14 @@
<MudChip T="string"
Href=@($"https://www.dlsite.com/maniax/circle/profile/=/maker_id/{Product.MakerId}.html")
Target="_blank"
Variant="Variant.Filled"
Variant="MudBlazor.Variant.Filled"
Icon="@Icons.Material.Outlined.Circle">@Product.Maker</MudChip>
@foreach (var creator in Product.Creators)
{
<MudChip T="string"
Href=@($"https://www.dlsite.com/maniax/fsr/=/keyword_creater/{creator.Name}")
Target="_blank"
Variant="Variant.Filled"
Variant="MudBlazor.Variant.Filled"
Icon="@Icons.Material.Filled.Person">@creator.Name</MudChip>
}
</span>
@@ -53,12 +54,26 @@
}
@* <div class="j-icon-2 j-icon-2-flag-@GetFlagClassSuffix(Product)"></div> *@
<div class="j-spacer"></div>
@if (Product.HasTrial || Product.HasChobit)
{
<div class="j-trial-container">
<div class="j-icon j-icon-headphones"></div>
</div>
}
<div class="j-product-indicators">
@if (Product.IsValid != true)
{
<div class="j-product-indicator j-product-indicator-invalid">
<div class="j-icon j-icon-warning-fill"></div>
</div>
}
@if (Product.Favorite)
{
<div class="j-product-indicator j-product-indicator-favorite">
<div class="j-icon j-icon-heart-fill"></div>
</div>
}
@if (Product.HasTrial || Product.HasChobit)
{
<div class="j-trial-container">
<div class="j-icon j-icon-headphones"></div>
</div>
}
</div>
</div>
</div>
@@ -66,6 +81,22 @@
[Parameter]
public required VoiceWorkSearchResult Product { get; set; }
private string GetCardClasses(VoiceWorkSearchResult voiceWork)
{
List<string> classNames = ["j-card", "j-voice-work-card"];
if (voiceWork.Status == (byte)VoiceWorkStatus.NewRelease)
{
classNames.Add("type-sale");
}
else if (voiceWork.Status == (byte)VoiceWorkStatus.NewAndUpcoming)
{
classNames.Add("type-new");
}
return string.Join(" ", classNames);
}
private string GetReleaseDateText(VoiceWorkSearchResult voiceWork)
{
if (voiceWork.SalesDate.HasValue)

View File

@@ -0,0 +1,75 @@
<RadzenStack Orientation="Radzen.Orientation.Vertical" Gap=".5em">
@if (string.IsNullOrWhiteSpace(Label) == false)
{
<RadzenLabel @bind-Text=Label Component="DropDownTextValueProperties" />
}
<RadzenTextBox class="j-input j-textbox" Value="@currentValue" Immediate="@Immediate" ValueChanged="@OnInnerValueChanged" Change="@OnInnerChange" />
</RadzenStack>
@code {
[Parameter]
public required string Label { get; set; }
[Parameter]
public string? Value { get; set; }
[Parameter]
public EventCallback<string?> ValueChanged { get; set; }
[Parameter]
public bool Immediate { get; set; }
[Parameter]
public int DebounceInterval { get; set; } = 300;
/// <summary>If true, also emit immediately on blur/Enter (in addition to debounced typing).</summary>
[Parameter]
public bool EmitOnCommit { get; set; } = false;
private string? currentValue;
private CancellationTokenSource? cancellationTokenSource;
protected override void OnParametersSet()
{
currentValue = Value;
}
private void OnInnerValueChanged(string? newValue)
{
currentValue = newValue;
_ = DebounceEmitAsync();
//Task.Run(DebounceEmitAsync);
}
private async Task DebounceEmitAsync()
{
cancellationTokenSource?.Cancel();
cancellationTokenSource?.Dispose();
cancellationTokenSource = new();
try
{
await Task.Delay(DebounceInterval, cancellationTokenSource.Token);
await ValueChanged.InvokeAsync(currentValue);
}
catch (TaskCanceledException)
{
}
}
private async Task OnInnerChange(object? _)
{
if (EmitOnCommit)
{
cancellationTokenSource?.Cancel();
await ValueChanged.InvokeAsync(currentValue);
}
}
public void Dispose()
{
cancellationTokenSource?.Cancel();
cancellationTokenSource?.Dispose();
}
}