diff --git a/DeepDrftManager/Components/Pages/Tracks/CmsGenreBrowser.razor b/DeepDrftManager/Components/Pages/Tracks/CmsGenreBrowser.razor new file mode 100644 index 0000000..e6e1901 --- /dev/null +++ b/DeepDrftManager/Components/Pages/Tracks/CmsGenreBrowser.razor @@ -0,0 +1,52 @@ +@using DeepDrftModels.DTOs + +@if (IsLoading) +{ + +} +else if (Genres.Count == 0) +{ + No genres found. +} +else +{ + + @foreach (var genre in Genres) + { + var isExpanded = ExpandedGenre == genre.Genre; + + +
+ + @genre.Genre + @genre.TrackCount track(s) + +
+
+ } +
+ + @if (ExpandedGenre is not null) + { + + @ExpandedGenre + + } +} + +@code { + [Parameter] public IReadOnlyList Genres { get; set; } = Array.Empty(); + [Parameter] public bool IsLoading { get; set; } + [Parameter] public string? ExpandedGenre { get; set; } + [Parameter] public EventCallback OnExpandedGenreChanged { get; set; } + + // The view model owns the toggle (selecting the open genre collapses it), so we pass the raw + // clicked genre rather than pre-computing the next state here — keeps the toggle logic single-sourced. + private async Task ToggleGenre(string genre) => + await OnExpandedGenreChanged.InvokeAsync(genre); + + private static string SwatchClass(bool isExpanded) => + isExpanded ? "cms-genre-swatch cms-genre-swatch--active" : "cms-genre-swatch"; +} diff --git a/DeepDrftManager/Components/Pages/Tracks/CmsGenreBrowser.razor.css b/DeepDrftManager/Components/Pages/Tracks/CmsGenreBrowser.razor.css new file mode 100644 index 0000000..34f29a3e --- /dev/null +++ b/DeepDrftManager/Components/Pages/Tracks/CmsGenreBrowser.razor.css @@ -0,0 +1,10 @@ +.cms-genre-swatch { + width: 100%; + height: 80px; + background-color: var(--mud-palette-action-default-hover); + transition: background-color 0.2s ease; +} + +.cms-genre-swatch--active { + background-color: var(--mud-palette-primary-hover); +} diff --git a/DeepDrftManager/Components/Pages/Tracks/TrackList.razor b/DeepDrftManager/Components/Pages/Tracks/TrackList.razor index 9db5052..3372307 100644 --- a/DeepDrftManager/Components/Pages/Tracks/TrackList.razor +++ b/DeepDrftManager/Components/Pages/Tracks/TrackList.razor @@ -59,7 +59,10 @@ } else { - Genre browser — coming in the next wave. + } @@ -99,6 +102,12 @@ StateHasChanged(); } + private void OnExpandedGenreChanged(string? genre) + { + VM.SetExpandedGenre(genre); + StateHasChanged(); + } + /// /// Backfill every track missing a waveform profile, one request at a time so a large backfill /// does not flood the API with concurrent WAV decodes. On completion, refreshes the grid's