Stable run with tailwind

This commit is contained in:
2026-07-18 12:08:14 +02:00
parent c9a5d3a79c
commit e3a735acda
116 changed files with 8230 additions and 66158 deletions
+105
View File
@@ -0,0 +1,105 @@
@namespace MidrandBooks.Components
@using Microsoft.AspNetCore.Components
@using MidrandBooks.Models
<div id="razor-book-grid" class="max-w-7xl mx-auto px-4 sm:px-6 py-6 space-y-6">
<!-- Filters Rail -->
<div class="flex flex-col md:flex-row gap-4 items-stretch md:items-center justify-between border-b border-slate-200/50 pb-5">
<!-- Search and Selection info -->
<div class="flex-1 max-w-md relative">
<span class="absolute inset-y-0 left-3 flex items-center text-slate-400">
<svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
</svg>
</span>
<input
type="text"
placeholder="Search manuscripts, authors, titles..."
value="@SearchQuery"
@oninput="HandleSearchInput"
class="w-full rounded-xl border border-slate-200 bg-white pl-9 pr-4 py-2 text-xs text-slate-800 placeholder-slate-400 outline-none focus:ring-2 focus:ring-violet-500/15 focus:border-violet-500 transition-all font-sans"
/>
</div>
<!-- Horizontal Scrollable Genre Filters -->
<div class="flex items-center gap-1.5 overflow-x-auto pb-1 max-w-full no-scrollbar">
<button
@onclick='() => SelectCategory("All")'
class="px-3.5 py-1.5 rounded-full text-[10px] font-mono font-bold tracking-wider uppercase transition-all whitespace-nowrap cursor-pointer border @(SelectedCategory == "All" ? "bg-violet-600 border-violet-600 text-white" : "bg-white text-slate-600 border-slate-200/80 hover:bg-slate-50")">
All Genres
</button>
@foreach (var cat in Categories)
{
<button
@onclick="() => SelectCategory(cat)"
class="px-3.5 py-1.5 rounded-full text-[10px] font-mono font-bold tracking-wider uppercase transition-all whitespace-nowrap cursor-pointer border @(SelectedCategory == cat ? "bg-violet-600 border-violet-600 text-white" : "bg-white text-slate-600 border-slate-200/80 hover:bg-slate-50")">
@cat
</button>
}
</div>
</div>
<!-- Active Catalog Grid -->
@if (FilteredBooks().Any())
{
<div class="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4 sm:gap-6">
@foreach (var book in FilteredBooks())
{
<BookCard Book="book" OnSelectBook="OnSelectBook" />
}
</div>
}
else
{
<div class="p-12 text-center border border-dashed border-slate-200 bg-slate-50/50 rounded-3xl space-y-2">
<svg class="mx-auto h-8 w-8 text-slate-300" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
</svg>
<h4 class="font-serif text-sm font-bold text-slate-700">No active publications match your search</h4>
<p class="text-[10px] text-slate-500 font-sans max-w-sm mx-auto leading-relaxed">
Try resetting your filters or browsing with different keywords. Direct self-published uploads require moderation prior to live activation.
</p>
</div>
}
</div>
@code {
[Parameter] public List<BookModel> Books { get; set; } = new();
[Parameter] public List<string> Categories { get; set; } = new();
[Parameter] public EventCallback<BookModel> OnSelectBook { get; set; }
private string SelectedCategory { get; set; } = "All";
private string SearchQuery { get; set; } = string.Empty;
private void SelectCategory(string category)
{
SelectedCategory = category;
}
private void HandleSearchInput(ChangeEventArgs e)
{
SearchQuery = e.Value?.ToString() ?? string.Empty;
}
private IEnumerable<BookModel> FilteredBooks()
{
var result = Books.Where(b => b.Status == "published");
if (SelectedCategory != "All")
{
result = result.Where(b => b.Category.Equals(SelectedCategory, StringComparison.OrdinalIgnoreCase));
}
if (!string.IsNullOrWhiteSpace(SearchQuery))
{
var query = SearchQuery.Trim().ToLower();
result = result.Where(b =>
b.Title.ToLower().Contains(query) ||
b.Author.ToLower().Contains(query) ||
b.Description.ToLower().Contains(query)
);
}
return result;
}
}