Skip to content

Commit

Permalink
Add ability to search statistics
Browse files Browse the repository at this point in the history
  • Loading branch information
LiamMorrow committed Sep 14, 2024
1 parent 20690ac commit ea20538
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 13 deletions.
28 changes: 23 additions & 5 deletions LiftLog.Ui/Pages/StatsPage.razor
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
<Select T="string" Options="SessionSelectOptions" Value="StatsState.Value.OverallViewSessionName" ValueChanged="v => { Dispatcher.Dispatch(new SetOverallViewSessionAction(v)); Dispatcher.Dispatch(new SetStatsIsDirtyAction(true)); Dispatcher.Dispatch(new FetchOverallStatsAction());}"></Select>
<Select data-cy="stats-time-selector" T="TimeSpan" Options="SelectTimeOptions" Value="StatsState.Value.OverallViewTime" ValueChanged="v => { Dispatcher.Dispatch(new SetOverallViewTimeAction(v)); Dispatcher.Dispatch(new SetStatsIsDirtyAction(true)); Dispatcher.Dispatch(new FetchOverallStatsAction()); }"></Select>
</div>
<div class="flex flex-col justify-between m-2">
<SearchInput SearchTerm=@SearchTerm OnSearch="@((st)=>{SearchTerm = st; StateHasChanged();})" />
</div>
@if (StatsState.Value.IsLoading)
{
<div class="flex flex-col justify-center h-full gap-4 text-on-surface">
Expand All @@ -33,7 +36,7 @@ else if ((StatsState.Value.OverallView?.SessionStats.Count ?? 0) == 0)
else if (!StatsState.Value.IsLoading && StatsState.Value.OverallView is not null)
{
var overallStats = StatsState.Value.OverallView;
<div class="grid grid-rows-2 grid-cols-2 gap-2 mb-2 px-2">
<div class="grid grid-rows-2 grid-cols-2 gap-2 mb-2 px-2 @HiddenOnSearch">
<SingleValueStatisticsCard>
<Title>Average time between sets</Title>
<Body>
Expand All @@ -60,30 +63,33 @@ else if (!StatsState.Value.IsLoading && StatsState.Value.OverallView is not null
</Body>
</SingleValueStatisticsCard>
</div>

<div class="flex flex-col gap-2">
@foreach(var pinnedStat in StatsState.Value.GetPinnedExercises().IndexedTuples())
@foreach(var pinnedStat in StatsState.Value.GetPinnedExercises().Where(SearchTermMatches).IndexedTuples())
{
<Card class="mx-2">
<StatGraphCardContent Title="@pinnedStat.Item.ExerciseName" Statistics="[pinnedStat.Item.Statistics, pinnedStat.Item.OneRepMaxStatistics]" RenderDelay="TimeSpan.FromMilliseconds(200 + pinnedStat.Index * 200)"/>
</Card>
}
@if (SettingsState.Value.ShowBodyweight && overallStats.BodyweightStats.Statistics.Any())
{
<Card class="mx-2">
<Card class=@CardClass >
<StatGraphCardContent Title="Bodyweight" Statistics="[overallStats.BodyweightStats]" RenderDelay="TimeSpan.FromMilliseconds(100)"/>
</Card>
}
<Card class="mx-2">
<Card class=@CardClass>
<StatGraphCardContent Title="Sessions" Statistics="overallStats.SessionStats" RenderDelay="TimeSpan.FromMilliseconds(200)"/>
</Card>
<CardList Items="@(overallStats.ExerciseStats.Where(x=>!StatsState.Value.IsExercisePinned(x)).IndexedTuples())">
<CardList Items="@(overallStats.ExerciseStats.Where(x=>!StatsState.Value.IsExercisePinned(x)).Where(SearchTermMatches).IndexedTuples())">
<StatGraphCardContent Title="@context.Item.ExerciseName" Statistics="[context.Item.Statistics, context.Item.OneRepMaxStatistics]" RenderDelay="TimeSpan.FromMilliseconds(200 + context.Index * 200)"/>
</CardList>
</div>
}

@code {

private string SearchTerm = "";

private List<Select<TimeSpan>.SelectOption> SelectTimeOptions =
[
new("7 days", TimeSpan.FromDays(7)),
Expand Down Expand Up @@ -116,4 +122,16 @@ else if (!StatsState.Value.IsLoading && StatsState.Value.OverallView is not null
await base.OnInitializedAsync();
}

private string HiddenOnSearch => string.IsNullOrWhiteSpace(SearchTerm) ? "" : "hidden";

private string CardClass => "mx-2 " + HiddenOnSearch;

private bool SearchTermMatches(ExerciseStatistics statistics)
{
if(string.IsNullOrWhiteSpace(SearchTerm))
{
return true;
}
return statistics.ExerciseName.Contains(SearchTerm, StringComparison.OrdinalIgnoreCase);
}
}
8 changes: 4 additions & 4 deletions LiftLog.Ui/Shared/Presentation/IconButton.razor
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
case IconButtonType.Standard:
<md-icon-button
@attributes="AdditionalAttributes"
class="pointer-events-auto"
class="pointer-events-auto @(AdditionalAttributes?.GetValueOrDefault("class")) "
@onclick="OnClick" @onclick:stopPropagation="true" @onclick:preventDefault="true"
disabled=@Disabled >
<md-icon>@Icon</md-icon>
Expand All @@ -12,7 +12,7 @@
case IconButtonType.Filled:
<md-filled-icon-button
@attributes="AdditionalAttributes"
class="pointer-events-auto"
class="pointer-events-auto @(AdditionalAttributes?.GetValueOrDefault("class")) "
@onclick="OnClick" @onclick:stopPropagation="true" @onclick:preventDefault="true"
disabled=@Disabled >
<md-icon>@Icon</md-icon>
Expand All @@ -21,7 +21,7 @@
case IconButtonType.FilledTonal:
<md-filled-tonal-icon-button
@attributes="AdditionalAttributes"
class="pointer-events-auto"
class="pointer-events-auto @(AdditionalAttributes?.GetValueOrDefault("class")) "
@onclick="OnClick" @onclick:stopPropagation="true" @onclick:preventDefault="true"
disabled=@Disabled >
<md-icon>@Icon</md-icon>
Expand All @@ -30,7 +30,7 @@
case IconButtonType.Outlined:
<md-outlined-icon-button
@attributes="AdditionalAttributes"
class="pointer-events-auto"
class="pointer-events-auto @(AdditionalAttributes?.GetValueOrDefault("class")) "
@onclick="OnClick" @onclick:stopPropagation="true" @onclick:preventDefault="true"
disabled=@Disabled
>
Expand Down
29 changes: 29 additions & 0 deletions LiftLog.Ui/Shared/Presentation/SearchInput.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<div class="relative flex flex-col rounded-full
text-on-surface">
<input type="text"
id="@ControlId"
class="
form-control
rounded-full
bg-surface-container-high px-12 py-4
placeholder-on-surface-variant
focus:outline-none focus:border-none"
placeholder="Search"
@bind="SearchTerm"
@oninput="e=>OnSearch.InvokeAsync(e.Value as string)" >
</input>
<md-icon class="absolute top-4 left-4">search</md-icon>
<IconButton OnClick=@(e=>OnSearch.InvokeAsync("")) Type="IconButtonType.Standard" Icon="close" class="absolute top-2 right-2"/>
<md-ripple></md-ripple>
<md-focus-ring for="@ControlId"></md-focus-ring>
</div>

@code {
private string ControlId = "a"+Guid.NewGuid().ToString().Replace("-", "");

[Parameter]
public string SearchTerm { get; set; } = "";

[Parameter]
public EventCallback<string> OnSearch { get; set; }
}
5 changes: 1 addition & 4 deletions LiftLog.Ui/Store/Program/ProgramEffects.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,7 @@ public class ProgramEffects(SessionService sessionService, IState<ProgramState>
public async Task FetchUpcomingSessions(IDispatcher dispatcher)
{
dispatcher.Dispatch(new SetUpcomingSessionsAction(RemoteData.Loading));
var numberOfUpcomingSessions = Math.Max(
state.Value.GetActivePlanSessionBlueprints().Count,
3
);
var numberOfUpcomingSessions = state.Value.GetActivePlanSessionBlueprints().Count;
var sessions = await sessionService
.GetUpcomingSessionsAsync(state.Value.GetActivePlanSessionBlueprints())
.Take(numberOfUpcomingSessions)
Expand Down

0 comments on commit ea20538

Please sign in to comment.