diff --git a/JSMR.UI.Blazor/Pages/Creators.razor b/JSMR.UI.Blazor/Pages/Creators.razor
index 0924a0c..927d201 100644
--- a/JSMR.UI.Blazor/Pages/Creators.razor
+++ b/JSMR.UI.Blazor/Pages/Creators.razor
@@ -11,7 +11,7 @@
Creators
-
+
@if (searchResults is null)
{
diff --git a/JSMR.UI.Blazor/Pages/Tags.razor b/JSMR.UI.Blazor/Pages/Tags.razor
index 166363f..e9ed345 100644
--- a/JSMR.UI.Blazor/Pages/Tags.razor
+++ b/JSMR.UI.Blazor/Pages/Tags.razor
@@ -11,7 +11,7 @@
Tags
-
+
@if (searchResults is null)
{
diff --git a/JSMR.UI.Blazor/Pages/VoiceWorks.razor b/JSMR.UI.Blazor/Pages/VoiceWorks.razor
index 6a9f470..f745589 100644
--- a/JSMR.UI.Blazor/Pages/VoiceWorks.razor
+++ b/JSMR.UI.Blazor/Pages/VoiceWorks.razor
@@ -1,6 +1,8 @@
@page "/voiceworks"
@using JSMR.Application.Common.Search
@using JSMR.Application.VoiceWorks.Queries.Search
+@using JSMR.Domain.Enums
+@using JSMR.Domain.ValueObjects
@using JSMR.UI.Blazor.Components
@using JSMR.UI.Blazor.Services
@inject VoiceWorksClient Client
@@ -12,40 +14,109 @@
-
+
+
+
+
+
+
+
+
-
- Available
- Upcoming
- All
-
+
-
- Not Blacklisted
- Favorite
- Blacklisted
- All
-
+
-
- Not Blacklisted
- Favorite (Exclude Blacklisted)
- Favorite (Include Blacklisted)
- Blacklisted
- All
-
+
+
+
+
+
-
- Not Blacklisted
- Favorite (Exclude Blacklisted)
- Favorite (Include Blacklisted)
- Blacklisted
- All
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -58,13 +129,75 @@
@code {
public string? Keywords { get; set; }
- public string? SelectedSaleStatus { get; set; } = string.Empty;
- public string? SelectedCircleStatus { get; set; } = string.Empty;
- public string? SelectedTagStatus { get; set; } = string.Empty;
- public string? SelectedCreatorStatus { get; set; } = string.Empty;
+ public SaleStatus? SelectedSaleStatus { get; set; }
+ public CircleStatus? SelectedCircleStatus { get; set; }
+ public TagStatus? SelectedTagStatus { get; set; }
+ public CreatorStatus? SelectedCreatorStatus { get; set; }
+ public bool ShowOnlyFavoriteWorks { get; set; }
+ public bool ShowOnlyInvalidWorks { get; set; }
+ public IEnumerable
SupportedLanguages { get; set; } = [];
+ public IEnumerable SelectedAgeRatings { get; set; } = [];
+ public DateTimeOffset? ReleaseDateStart { get; set; }
+ public DateTimeOffset? ReleaseDateEnd { get; set; }
public int PageNumber { get; set; } = 1;
public int PageSize { get; set; } = 100;
+ IEnumerable> SaleStatuses =
+ [
+ new(SaleStatus.Available, "Available"),
+ new(SaleStatus.Upcoming, "Upcoming"),
+ new(null, "All")
+ ];
+
+ List> BasicItems =
+ [
+ new() { Text = "Available", Value = SaleStatus.Available },
+ new() { Text = "Upcoming", Value = SaleStatus.Upcoming },
+ new() { Text = "All", Value = null }
+ ];
+
+ List> CircleStatuses =
+ [
+ new() { Text = "Not Blacklisted", Value = CircleStatus.NotBlacklisted },
+ new() { Text = "Favorites", Value = CircleStatus.Favorited },
+ new() { Text = "Blacklisted", Value = CircleStatus.Blacklisted },
+ new() { Text = "All", Value = null }
+ ];
+
+ List> TagStatuses =
+ [
+ new() { Text = "Not Blacklisted", Value = TagStatus.NotBlacklisted },
+ new() { Text = "Favorites (Exclude Blacklisted)", Value = TagStatus.FavoriteExcludeBlacklist },
+ new() { Text = "Favorites (Include Blacklisted)", Value = TagStatus.FavoriteIncludeBlacklist },
+ new() { Text = "Blacklisted", Value = TagStatus.Blacklisted },
+ new() { Text = "All", Value = null }
+ ];
+
+ List> CreatorStatuses =
+ [
+ new() { Text = "Not Blacklisted", Value = CreatorStatus.NotBlacklisted },
+ new() { Text = "Favorites (Exclude Blacklisted)", Value = CreatorStatus.FavoriteExcludeBlacklist },
+ new() { Text = "Favorites (Include Blacklisted)", Value = CreatorStatus.FavoriteIncludeBlacklist },
+ new() { Text = "Blacklisted", Value = CreatorStatus.Blacklisted },
+ new() { Text = "All", Value = null }
+ ];
+
+ List> Languages =
+ [
+ new() { Text = "Japanese", Value = Language.Japanese },
+ new() { Text = "English", Value = Language.English },
+ new() { Text = "Chinese (Traditional)", Value = Language.ChineseTraditional },
+ new() { Text = "Chinese (Simplified)", Value = Language.ChineseSimplified },
+ new() { Text = "Korean", Value = Language.Korean }
+ ];
+
+ List> AgeRatings =
+ [
+ new() { Text = "All Ages", Value = AgeRating.AllAges },
+ new() { Text = "R15", Value = AgeRating.R15 },
+ new() { Text = "R18", Value = AgeRating.R18 }
+ ];
+
SearchResult? searchResults;
protected override async Task OnInitializedAsync()
@@ -85,11 +218,16 @@
Criteria = new()
{
Keywords = Keywords,
- SaleStatus = string.IsNullOrWhiteSpace(SelectedSaleStatus) == false ? Enum.Parse(SelectedSaleStatus) : null,
- CircleStatus = string.IsNullOrWhiteSpace(SelectedCircleStatus) == false ? Enum.Parse(SelectedCircleStatus) : null,
- TagStatus = string.IsNullOrWhiteSpace(SelectedTagStatus) == false ? Enum.Parse(SelectedTagStatus) : null,
- CreatorStatus = string.IsNullOrWhiteSpace(SelectedCreatorStatus) == false ? Enum.Parse(SelectedCreatorStatus) : null,
- //SupportedLanguages = [Domain.Enums.Language.English]
+ SaleStatus = SelectedSaleStatus,
+ CircleStatus = SelectedCircleStatus,
+ TagStatus = SelectedTagStatus,
+ CreatorStatus = SelectedCreatorStatus,
+ ShowFavoriteVoiceWorks = ShowOnlyFavoriteWorks,
+ ShowInvalidVoiceWorks = ShowOnlyInvalidWorks,
+ SupportedLanguages = [.. SupportedLanguages],
+ AgeRatings = [.. SelectedAgeRatings],
+ ReleaseDateStart = ReleaseDateStart != null ? DateOnly.FromDateTime(ReleaseDateStart.Value.Date) : null,
+ ReleaseDateEnd = ReleaseDateEnd != null ? DateOnly.FromDateTime(ReleaseDateEnd.Value.Date) : null
},
SortOptions =
[
@@ -111,30 +249,66 @@
await UpdateDataAsync(true);
}
- public async Task OnSaleStatusChanged(string? saleStatus)
+ public async Task OnSaleStatusChanged(SaleStatus? saleStatus)
{
SelectedSaleStatus = saleStatus;
await UpdateDataAsync(true);
}
- public async Task OnCircleStatusChanged(string? circleStatus)
+ public async Task OnCircleStatusChanged(CircleStatus? circleStatus)
{
SelectedCircleStatus = circleStatus;
await UpdateDataAsync(true);
}
- public async Task OnTagStatusChanged(string? tagStatus)
+ public async Task OnTagStatusChanged(TagStatus? tagStatus)
{
SelectedTagStatus = tagStatus;
await UpdateDataAsync(true);
}
- public async Task OnCreatorStatusChanged(string? creatorStatus)
+ public async Task OnCreatorStatusChanged(CreatorStatus? creatorStatus)
{
SelectedCreatorStatus = creatorStatus;
await UpdateDataAsync(true);
}
+ public async Task OnSupportedLanguagesChanged(IEnumerable languages)
+ {
+ SupportedLanguages = languages;
+ await UpdateDataAsync(true);
+ }
+
+ public async Task OnAgeRatingsChanged(IEnumerable ageRatings)
+ {
+ SelectedAgeRatings = ageRatings;
+ await UpdateDataAsync(true);
+ }
+
+ public async Task OnShowOnlyFavoriteWorksChanged(bool showOnlyFavoriteWorks)
+ {
+ ShowOnlyFavoriteWorks = showOnlyFavoriteWorks;
+ await UpdateDataAsync(true);
+ }
+
+ public async Task OnShowOnlyInvalidWorksChanged(bool showOnlyInvalidWorks)
+ {
+ ShowOnlyInvalidWorks = showOnlyInvalidWorks;
+ await UpdateDataAsync(true);
+ }
+
+ public async Task OnReleaseDateStartChanged(DateTimeOffset? releaseDateStart)
+ {
+ ReleaseDateStart = releaseDateStart;
+ await UpdateDataAsync(true);
+ }
+
+ public async Task OnReleaseDateEndChanged(DateTimeOffset? releaseDateEnd)
+ {
+ ReleaseDateEnd = releaseDateEnd;
+ await UpdateDataAsync(true);
+ }
+
public async Task OnPageNumberChanged(int newPageNumber)
{
PageNumber = newPageNumber;
@@ -149,9 +323,7 @@
private VoiceWorkSortField GetSortField()
{
- SaleStatus? saleStatus = string.IsNullOrWhiteSpace(SelectedSaleStatus) == false ? Enum.Parse(SelectedSaleStatus) : null;
-
- switch (saleStatus)
+ switch (SelectedSaleStatus)
{
case SaleStatus.Available:
return VoiceWorkSortField.ReleaseDate;
diff --git a/JSMR.UI.Blazor/Program.cs b/JSMR.UI.Blazor/Program.cs
index 1c28932..4ac2619 100644
--- a/JSMR.UI.Blazor/Program.cs
+++ b/JSMR.UI.Blazor/Program.cs
@@ -1,8 +1,10 @@
+using Bit.BlazorUI;
using JSMR.UI.Blazor;
using JSMR.UI.Blazor.Services;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using MudBlazor.Services;
+using Radzen;
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add("#app");
@@ -14,6 +16,8 @@ Console.WriteLine(apiBase);
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(apiBase) });
builder.Services.AddMudServices();
+builder.Services.AddRadzenComponents();
+builder.Services.AddBitBlazorUIServices();
builder.Services.AddScoped();
diff --git a/JSMR.UI.Blazor/_Imports.razor b/JSMR.UI.Blazor/_Imports.razor
index 8c7b858..6475b8c 100644
--- a/JSMR.UI.Blazor/_Imports.razor
+++ b/JSMR.UI.Blazor/_Imports.razor
@@ -8,4 +8,7 @@
@using Microsoft.JSInterop
@using JSMR.UI.Blazor
@using JSMR.UI.Blazor.Layout
-@using MudBlazor
\ No newline at end of file
+@using MudBlazor
+@using Radzen
+@using Radzen.Blazor
+@using Bit.BlazorUI
\ No newline at end of file
diff --git a/JSMR.UI.Blazor/wwwroot/css/app.css b/JSMR.UI.Blazor/wwwroot/css/app.css
index cdcb175..2cda92b 100644
--- a/JSMR.UI.Blazor/wwwroot/css/app.css
+++ b/JSMR.UI.Blazor/wwwroot/css/app.css
@@ -150,6 +150,11 @@ code {
grid-column: span 4;
}
+.search-filter-control {
+ display: flex;
+ align-items: center;
+}
+
.items-container {
display: grid;
grid-column-gap: 1.2em;
@@ -335,6 +340,16 @@ code {
background-image: var(--card-background-image);
}
+/* Input */
+.j-input {
+ background: rgb(0,20,34);
+ border: 1px solid #304562;
+}
+
+.j-textbox {
+
+}
+
/* Image */
.j-image-container {
@@ -357,6 +372,7 @@ code {
}
.j-voice-work-card {
+ position: relative;
display: flex;
gap: 1rem;
background-image: linear-gradient(0deg, rgb(30, 53, 69), rgb(39, 59, 73));
@@ -367,6 +383,36 @@ code {
border-right-color: rgb(72, 88, 99);
}
+.j-voice-work-card[class*="type-sale"]::before {
+ background-image: url(../images/web/common/icon_sale_status_01.png);
+ width: 72px;
+ height: 72px;
+ position: absolute;
+ display: block;
+ top: 0;
+ left: 0;
+ z-index: 2;
+ content: "";
+ background-position: 0 -432px;
+ background-size: cover;
+ pointer-events: none;
+}
+
+.j-voice-work-card[class*="type-new"]::before {
+ background-image: url(../images/web/common/icon_sale_status_01.png);
+ width: 72px;
+ height: 72px;
+ position: absolute;
+ display: block;
+ top: 0;
+ left: 0;
+ z-index: 2;
+ content: "";
+ background-position: 0 -504px;
+ background-size: cover;
+ pointer-events: none;
+}
+
.j-voice-work-image-container {
width: 240px;
width: 300px;
@@ -482,6 +528,29 @@ code {
height: 16px;
}
+.j-product-indicators {
+ display: flex;
+ gap: .5rem;
+}
+
+.j-product-indicator {
+ border-width: 1px;
+ border-style: solid;
+ border-image: none;
+ padding: 0.5rem;
+ border-radius: 100%;
+ border-color: var(--product-title-text-color);
+}
+
+.j-product-indicator-favorite {
+ border-color: #f04885;
+ background: #f048852b;
+}
+
+.j-product-indicator-favorite > .j-icon {
+ background-color: #f04885;
+}
+
/* Tags */
.j-tags {
display: flex;
@@ -542,6 +611,22 @@ code {
mask-image: url("../svg/headphones.svg");
}
+.j-icon-heart {
+ mask-image: url("../svg/heart.svg");
+}
+
+.j-icon-heart-fill {
+ mask-image: url("../svg/heart-fill.svg");
+}
+
+.j-icon-warning {
+ mask-image: url("../svg/warning.svg");
+}
+
+.j-icon-warning-fill {
+ mask-image: url("../svg/warning-fill.svg");
+}
+
.j-icon-2 {
background-repeat: no-repeat;
background-position: center;
diff --git a/JSMR.UI.Blazor/wwwroot/css/bit-blazor.css b/JSMR.UI.Blazor/wwwroot/css/bit-blazor.css
new file mode 100644
index 0000000..a1cf88a
--- /dev/null
+++ b/JSMR.UI.Blazor/wwwroot/css/bit-blazor.css
@@ -0,0 +1,41 @@
+.bit-tfl-inp,
+.bit-drp-wrp,
+.bit-dtp-wrp {
+ border: 1px solid var(--input-border-color);
+ background-color: var(--input-background-color);
+ transition: background-color .2s,color .2s,border-color .2s,box-shadow .2s;
+ padding: .25rem .5rem;
+}
+
+.bit-tfl-fgp {
+ border: 1px solid var(--input-border-color);
+}
+
+.bit-tfl-inp:hover,
+.bit-drp-wrp:hover {
+ border: 1px solid var(--input-hover-border-color);
+ background-color: var(--input-background-color);
+}
+
+.bit-tfl-inp:focus,
+.bit-drp-wrp:focus {
+ background-color: var(--input-background-color);
+ border: 1px solid var(--input-focus-border-color);
+ box-shadow: var(--input-focus-box-shadow);
+}
+
+/* DropDownList */
+.bit-drp-cal {
+ background-color: var(--input-background-color);
+}
+
+.bit-drp-itm:hover {
+ color: #ffffffde;
+ background: rgba(255,255,255,.03);
+}
+
+.bit-drp-sel,
+.bit-drp-sel:hover {
+ color: #ffffffde;
+ background: rgba(100,181,246,.16);
+}
\ No newline at end of file
diff --git a/JSMR.UI.Blazor/wwwroot/css/jsmr-mud-blazor.css b/JSMR.UI.Blazor/wwwroot/css/mud-blazor.css
similarity index 100%
rename from JSMR.UI.Blazor/wwwroot/css/jsmr-mud-blazor.css
rename to JSMR.UI.Blazor/wwwroot/css/mud-blazor.css
diff --git a/JSMR.UI.Blazor/wwwroot/css/radzen.css b/JSMR.UI.Blazor/wwwroot/css/radzen.css
new file mode 100644
index 0000000..b2229e2
--- /dev/null
+++ b/JSMR.UI.Blazor/wwwroot/css/radzen.css
@@ -0,0 +1,48 @@
+.rz-timespanpicker > .rz-inputtext.j-input,
+.rz-colorpicker.j-input,
+.rz-lookup-search input.j-input,
+.rz-numeric.j-input,
+.rz-datepicker > .rz-inputtext.j-input,
+.rz-multiselect, .rz-dropdown.j-input,
+.mask.j-input,
+.rz-textarea.j-input,
+.rz-textbox.j-input {
+ border: 1px solid var(--input-border-color);
+ background-color: var(--input-background-color);
+ transition: background-color .2s,color .2s,border-color .2s,box-shadow .2s;
+ padding: .25rem .5rem;
+}
+
+.j-input.rz-form-field:hover .rz-form-field-content,
+.j-input.rz-autocomplete:hover:not(.rz-state-disabled),
+.j-input.rz-timespanpicker > .rz-inputtext:not(:disabled):not(.rz-state-disabled):hover,
+.j-input.rz-colorpicker:not(:disabled):not(.rz-state-disabled):hover,
+.j-input.rz-lookup-search input:not(:disabled):not(.rz-state-disabled):hover,
+.j-input.rz-numeric:not(:disabled):not(.rz-state-disabled):hover,
+.j-input.rz-datepicker > .rz-inputtext:not(:disabled):not(.rz-state-disabled):hover,
+.j-input.rz-multiselect:not(:disabled):not(.rz-state-disabled):hover,
+.j-input.rz-dropdown:not(:disabled):not(.rz-state-disabled):hover,
+.j-input.mask:not(:disabled):not(.rz-state-disabled):hover,
+.j-input.rz-textarea:not(:disabled):not(.rz-state-disabled):hover,
+.j-input.rz-textbox:not(:disabled):not(.rz-state-disabled):hover {
+ border: 1px solid var(--input-hover-border-color);
+ background-color: var(--input-background-color);
+}
+
+.j-input.rz-form-field.rz-state-focused .rz-form-field-content,
+.j-input.rz-numeric:focus-within:not(.rz-state-disabled),
+.j-input.rz-autocomplete:focus-within:not(.rz-state-disabled),
+.j-input.rz-timespanpicker > .rz-inputtext:not(:disabled):not(.rz-state-disabled):focus,
+.j-input.rz-colorpicker:not(:disabled):not(.rz-state-disabled):focus,
+.j-input.rz-lookup-search input:not(:disabled):not(.rz-state-disabled):focus,
+.j-input.rz-numeric:not(:disabled):not(.rz-state-disabled):focus,
+.j-input.rz-datepicker > .rz-inputtext:not(:disabled):not(.rz-state-disabled):focus,
+.j-input.rz-multiselect:not(:disabled):not(.rz-state-disabled):focus,
+.j-input.rz-dropdown:not(:disabled):not(.rz-state-disabled):focus,
+.j-input.mask:not(:disabled):not(.rz-state-disabled):focus,
+.j-input.rz-textarea:not(:disabled):not(.rz-state-disabled):focus,
+.j-input.rz-textbox:not(:disabled):not(.rz-state-disabled):focus {
+ background-color: var(--input-background-color);
+ border: 1px solid var(--input-focus-border-color);
+ box-shadow: var(--input-focus-box-shadow);
+}
\ No newline at end of file
diff --git a/JSMR.UI.Blazor/wwwroot/css/theme-base.css b/JSMR.UI.Blazor/wwwroot/css/theme-base.css
index 9a851a2..9786bff 100644
--- a/JSMR.UI.Blazor/wwwroot/css/theme-base.css
+++ b/JSMR.UI.Blazor/wwwroot/css/theme-base.css
@@ -5,5 +5,5 @@ body {
}
label {
- font-weight: 600;
+ font-weight: 500;
}
\ No newline at end of file
diff --git a/JSMR.UI.Blazor/wwwroot/css/theme-frozen.css b/JSMR.UI.Blazor/wwwroot/css/theme-frozen.css
index f56b902..22c4de6 100644
--- a/JSMR.UI.Blazor/wwwroot/css/theme-frozen.css
+++ b/JSMR.UI.Blazor/wwwroot/css/theme-frozen.css
@@ -34,6 +34,11 @@
--card-border-left-color: #212630;
--card-border-right-color: #212531;
--card-border-bottom-color: #212530;
+ --input-border-color: #304562;
+ --input-hover-border-color: #64b5f6;
+ --input-background-color: rgb(0,20,34);
+ --input-focus-border-color: #64b5f6;
+ --input-focus-box-shadow: 0 0 0 1px #93cbf9;
}
/*
diff --git a/JSMR.UI.Blazor/wwwroot/index.html b/JSMR.UI.Blazor/wwwroot/index.html
index 324e6fd..af36257 100644
--- a/JSMR.UI.Blazor/wwwroot/index.html
+++ b/JSMR.UI.Blazor/wwwroot/index.html
@@ -1,5 +1,5 @@
-
+
@@ -16,9 +16,14 @@
+
+
-
+
+
+
+
@@ -46,6 +51,7 @@
+
diff --git a/JSMR.UI.Blazor/wwwroot/svg/warning-fill.svg b/JSMR.UI.Blazor/wwwroot/svg/warning-fill.svg
new file mode 100644
index 0000000..cbde20f
--- /dev/null
+++ b/JSMR.UI.Blazor/wwwroot/svg/warning-fill.svg
@@ -0,0 +1,3 @@
+