Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions lib/bike_brigade/riders/rider_search.ex
Original file line number Diff line number Diff line change
Expand Up @@ -357,4 +357,27 @@ defmodule BikeBrigade.Riders.RiderSearch do
query
|> where(as(:latest_campaign).delivery_start > ago(1, ^period))
end

defp apply_filter(%Filter{type: :signed_up, search: period}, query, _filters)
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
when period in ~w(today yesterday) do
today = Date.utc_today()

{start_date, end_date} =
case period do
"yesterday" -> {Date.add(today, -1), today}
_today -> {today, Date.add(today, 1)}
end

start_dt = DateTime.new!(start_date, ~T[00:00:00])
end_dt = DateTime.new!(end_date, ~T[00:00:00])

query
|> where(as(:rider).signed_up_on >= ^start_dt and as(:rider).signed_up_on < ^end_dt)
end

defp apply_filter(%Filter{type: :signed_up, search: period}, query, _filters)
when period in ~w(week month year) do
query
|> where(as(:rider).signed_up_on > ago(1, ^period))
end
Comment thread
neal-bpm marked this conversation as resolved.
end
34 changes: 30 additions & 4 deletions lib/bike_brigade_web/live/rider_live/index.ex
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,29 @@ defmodule BikeBrigadeWeb.RiderLive.Index do
|> Enum.map(&%Filter{type: :active, search: &1})
@capacities ~w(large medium small)
|> Enum.map(&%Filter{type: :capacity, search: &1})
@signed_ups ~w(today yesterday week month year)
|> Enum.map(&%Filter{type: :signed_up, search: &1})

defstruct name: nil, phone: nil, tags: [], programs: [], active: [], capacity: []
defstruct name: nil,
phone: nil,
tags: [],
programs: [],
active: [],
capacity: [],
signed_up: []

@type t :: %__MODULE__{
name: Filter.t() | nil,
tags: list(Filter.t()),
programs: list(Filter.t()),
active: list(Filter.t()),
capacity: list(Filter.t())
capacity: list(Filter.t()),
signed_up: list(Filter.t())
}

@spec suggest(t(), String.t()) :: t()
def suggest(suggestions, "") do
%{suggestions | name: nil, tags: [], programs: [], active: [], capacity: []}
%{suggestions | name: nil, tags: [], programs: [], active: [], capacity: [], signed_up: []}
Comment thread
neal-bpm marked this conversation as resolved.
Comment thread
neal-bpm marked this conversation as resolved.
end

def suggest(suggestions, search) do
Expand Down Expand Up @@ -72,6 +81,13 @@ defmodule BikeBrigadeWeb.RiderLive.Index do

%__MODULE__{capacity: capacity}

["signed_up", signed_up] ->
signed_ups =
@signed_ups
|> Enum.filter(&String.starts_with?(&1.search, signed_up))

%__MODULE__{signed_up: signed_ups}

[search] ->
tags =
if String.length(search) < 3 do
Expand Down Expand Up @@ -105,7 +121,8 @@ defmodule BikeBrigadeWeb.RiderLive.Index do
tags: tags,
programs: programs,
active: @actives,
capacity: @capacities
capacity: @capacities,
signed_up: @signed_ups
}

[_, _] ->
Expand Down Expand Up @@ -498,6 +515,14 @@ defmodule BikeBrigadeWeb.RiderLive.Index do
<% end %>
</div>
<% end %>
<%= if @suggestions.signed_up != [] do %>
<h3 class="my-1 text-xs font-medium tracking-wider text-left text-gray-500 uppercase">
Signed Up
</h3>
<div :for={period <- @suggestions.signed_up} class="flex flex-col my-2">
<.suggestion filter={period} />
</div>
<% end %>
</div>
<div>
<%= if @suggestions.capacity != [] do %>
Expand Down Expand Up @@ -631,6 +656,7 @@ defmodule BikeBrigadeWeb.RiderLive.Index do
:active -> "text-amber-900 bg-amber-100"
:capacity -> "text-rose-900 bg-rose-100"
:phone -> "text-cyan-900 bg-cyan-100"
:signed_up -> "text-blue-900 bg-blue-100"
end
end

Expand Down
2 changes: 1 addition & 1 deletion lib/bike_brigade_web/live/rider_live/index.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
value={display_search(@search)}
autocomplete="off"
class="w-full placeholder-gray-400 border-transparent appearance-none focus:border-transparent outline-transparent ring-transparent focus:ring-0"
placeholder="Name, tag, capacity, last active"
placeholder="Name, tag, capacity, last active, signed up"
tabindex="1"
/>
<%= if @rider_search.filters != [] do %>
Expand Down
96 changes: 96 additions & 0 deletions test/bike_brigade/riders/rider_search_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,103 @@ defmodule BikeBrigade.Riders.RiderSearchTest do
link_rider_to_campaign(rider_id, campaign.id)
end

describe "signed_up filter" do
test "today - includes rider who signed up today" do
today_start = DateTime.new!(Date.utc_today(), ~T[00:00:00])
rider = fixture(:rider, %{signed_up_on: DateTime.add(today_start, 1, :hour)})

{_rs, results} =
RiderSearch.new(filters: [%Filter{type: :signed_up, search: "today"}])
|> RiderSearch.fetch()

assert rider_in_results?(results, rider.id)
end

test "today - excludes rider who signed up yesterday" do
yesterday = Date.add(Date.utc_today(), -1)
yesterday_time = DateTime.new!(yesterday, ~T[12:00:00])
rider = fixture(:rider, %{signed_up_on: yesterday_time})

{_rs, results} =
RiderSearch.new(filters: [%Filter{type: :signed_up, search: "today"}])
|> RiderSearch.fetch()

refute rider_in_results?(results, rider.id)
end

test "yesterday - includes rider who signed up yesterday" do
yesterday = Date.add(Date.utc_today(), -1)
yesterday_time = DateTime.new!(yesterday, ~T[12:00:00])
rider = fixture(:rider, %{signed_up_on: yesterday_time})

{_rs, results} =
RiderSearch.new(filters: [%Filter{type: :signed_up, search: "yesterday"}])
|> RiderSearch.fetch()

assert rider_in_results?(results, rider.id)
end

test "yesterday - excludes rider who signed up today" do
today_start = DateTime.new!(Date.utc_today(), ~T[00:00:00])
rider = fixture(:rider, %{signed_up_on: DateTime.add(today_start, 1, :hour)})

{_rs, results} =
RiderSearch.new(filters: [%Filter{type: :signed_up, search: "yesterday"}])
|> RiderSearch.fetch()

refute rider_in_results?(results, rider.id)
end

test "week - includes rider who signed up within the past week" do
rider = fixture(:rider, %{signed_up_on: signed_up_ago(5, :day)})

{_rs, results} =
RiderSearch.new(filters: [%Filter{type: :signed_up, search: "week"}])
|> RiderSearch.fetch()

assert rider_in_results?(results, rider.id)
end

test "week - excludes rider who signed up more than a week ago" do
rider = fixture(:rider, %{signed_up_on: signed_up_ago(8, :day)})

{_rs, results} =
RiderSearch.new(filters: [%Filter{type: :signed_up, search: "week"}])
|> RiderSearch.fetch()

refute rider_in_results?(results, rider.id)
end

test "month - includes rider who signed up within the past month" do
rider = fixture(:rider, %{signed_up_on: signed_up_ago(14, :day)})

{_rs, results} =
RiderSearch.new(filters: [%Filter{type: :signed_up, search: "month"}])
|> RiderSearch.fetch()

assert rider_in_results?(results, rider.id)
end

test "year - includes rider who signed up within the past year" do
rider = fixture(:rider, %{signed_up_on: signed_up_ago(180, :day)})

{_rs, results} =
RiderSearch.new(filters: [%Filter{type: :signed_up, search: "year"}])
|> RiderSearch.fetch()

assert rider_in_results?(results, rider.id)
end
end

defp rider_in_results?(results, id) do
Enum.find(results.page, &(&1.id == id))
end

# Helper to create a DateTime a specified duration in the past
# @param amount - number of time units (positive, will be negated)
# @param unit - time unit (:day, :hour, :second, etc.)
# @return DateTime in UTC
defp signed_up_ago(amount, unit) do
DateTime.utc_now() |> DateTime.add(-amount, unit)
end
end
Loading