Skip to content

Commit

Permalink
Merge branch 'main' into bump-deps
Browse files Browse the repository at this point in the history
  • Loading branch information
mveytsman committed Nov 22, 2023
2 parents b136681 + 6e9e712 commit bdf9951
Show file tree
Hide file tree
Showing 16 changed files with 278 additions and 86 deletions.
36 changes: 36 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
name: Bug report
about: Use this template for reporting bugs.
---

**Describe the bug**

< Thank you for filing an issue. Please replace this text with a description of the bug you have encountered. >

**Steps to Reproduce**

If possible, please provide steps to reproduce the behaviour:

< insert steps to recreate >

**Expected behavior**

Describe what you expected to happen.

**Screenshots**

If applicable, add screenshots of the bug in action!

**Environment (please complete the following information):**

- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]

**Additional context**

Add any other context about the problem here.




10 changes: 7 additions & 3 deletions lib/bike_brigade/riders/rider_search.ex
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,10 @@ defmodule BikeBrigade.Riders.RiderSearch do
@spec apply_filter(Filter.t(), Ecto.Query.t()) :: Ecto.Query.t()
defp apply_filter(%Filter{type: :name, search: search}, query) do
query
|> where(ilike(as(:rider).name, ^"#{search}%") or ilike(as(:rider).name, ^"% #{search}%"))
|> where(
fragment("unaccent(?) ilike unaccent(?)", as(:rider).name, ^"%#{search}%") or
fragment("unaccent(?) ilike unaccent(?)", as(:rider).name, ^"% #{search}%")
)
end

defp apply_filter(%Filter{type: :phone, search: search}, query) do
Expand All @@ -239,8 +242,9 @@ defmodule BikeBrigade.Riders.RiderSearch do
defp apply_filter(%Filter{type: :name_or_phone, search: search}, query) do
query
|> where(
ilike(as(:rider).name, ^"#{search}%") or ilike(as(:rider).name, ^"% #{search}%") or
like(as(:rider).phone, ^"%#{search}%")
fragment("unaccent(?) ilike unaccent(?)", as(:rider).name, ^"%#{search}%") or
fragment("unaccent(?) ilike unaccent(?)", as(:rider).name, ^"% #{search}%") or
like(as(:rider).phone, ^"%#{search}%")
)
end

Expand Down
2 changes: 1 addition & 1 deletion lib/bike_brigade/tasks/mailchimp_importer.ex
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ defmodule BikeBrigade.Tasks.MailchimpImporter do

def notify_location_error(rider) do
error_message = """
We had trouble with the address for #{rider.name}. Please edit manually: #{~p"/riders/#{rider}/edit"}, and don't forget to remove the `invalid_location` tag!
We had trouble with the address for #{rider.name}. Please edit manually: #{~p"/riders/#{rider}/show/edit"}, and don't forget to remove the `invalid_location` tag!
"""

Task.start(Slack.Operations, :post_message!, [error_message])
Expand Down
10 changes: 10 additions & 0 deletions lib/bike_brigade_web/components/layouts.ex
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,16 @@ defmodule BikeBrigadeWeb.Layouts do
</:icon>
My Profile
</.sidebar_link>
<!-- Rider Specific links -->
<div :if={!@is_dispatcher}>
<.sidebar_link selected={@current_page == :itinerary} href={~p"/itinerary"}>
<:icon>
<Heroicons.calendar_days solid />
</:icon>
Itinerary
</.sidebar_link>
</div>
<.sidebar_link selected={@current_page == :logout} href={~p"/logout"} method="post">
<:icon>
<Heroicons.arrow_left_on_rectangle solid />
Expand Down
55 changes: 28 additions & 27 deletions lib/bike_brigade_web/components/live_location.ex
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,7 @@ defmodule BikeBrigadeWeb.Components.LiveLocation do
location = %Location{}
changeset = Location.changeset(location)

{location, changeset
}
{location, changeset}
end

form = Phoenix.HTML.FormData.to_form(changeset, as: as)
Expand Down Expand Up @@ -173,8 +172,8 @@ defmodule BikeBrigadeWeb.Components.LiveLocation do
</button>
</div>
<div class={"#{if !@open, do: "hidden"} my-1 edit-mode"}>
<div class="flex space-x-1">
<div class="w-1/2">
<div class="flex flex-col md:flex-row items-baseline space-x-1">
<div class="w-full md:w-1/2">
<label class="block text-xs font-medium leading-5 text-gray-700">
Address
</label>
Expand All @@ -188,30 +187,32 @@ defmodule BikeBrigadeWeb.Components.LiveLocation do
</div>
<%= error_tag(@form, :address, show_field: false) %>
</div>
<div class="w-1/4">
<label class="block text-xs font-medium leading-5 text-gray-700">
Unit
</label>
<div class="mt-1 rounded-md shadow-sm">
<%= text_input(@form, :unit,
phx_change: "change",
phx_target: @myself,
class:
"block w-full px-3 py-2 placeholder-gray-400 transition duration-150 ease-in-out border border-gray-300 rounded-md appearance-none focus:outline-none focus:ring-blue focus:border-blue-300 sm:text-sm sm:leading-5"
) %>
<div class="flex w-full md:w-1/2 items-baseline">
<div class="w-1/2 mr-1">
<label class="block text-xs font-medium leading-5 text-gray-700">
Unit
</label>
<div class="mt-1 rounded-md shadow-sm">
<%= text_input(@form, :unit,
phx_change: "change",
phx_target: @myself,
class:
"block w-full px-3 py-2 placeholder-gray-400 transition duration-150 ease-in-out border border-gray-300 rounded-md appearance-none focus:outline-none focus:ring-blue focus:border-blue-300 sm:text-sm sm:leading-5"
) %>
</div>
</div>
</div>
<div class="w-1/4">
<label class="block text-xs font-medium leading-5 text-gray-700">
Buzzer
</label>
<div class="mt-1 rounded-md shadow-sm">
<%= text_input(@form, :buzzer,
phx_change: "change",
phx_target: @myself,
class:
"block w-full px-3 py-2 placeholder-gray-400 transition duration-150 ease-in-out border border-gray-300 rounded-md appearance-none focus:outline-none focus:ring-blue focus:border-blue-300 sm:text-sm sm:leading-5"
) %>
<div class="mt-2 w-1/2">
<label class="block text-xs font-medium leading-5 text-gray-700">
Buzzer
</label>
<div class="mt-1 rounded-md shadow-sm">
<%= text_input(@form, :buzzer,
phx_change: "change",
phx_target: @myself,
class:
"block w-full px-3 py-2 placeholder-gray-400 transition duration-150 ease-in-out border border-gray-300 rounded-md appearance-none focus:outline-none focus:ring-blue focus:border-blue-300 sm:text-sm sm:leading-5"
) %>
</div>
</div>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion lib/bike_brigade_web/core_components.ex
Original file line number Diff line number Diff line change
Expand Up @@ -718,7 +718,7 @@ defmodule BikeBrigadeWeb.CoreComponents do
phx-window-keydown={hide_modal(@on_cancel, @id)}
phx-key="escape"
phx-click-away={hide_modal(@on_cancel, @id)}
class="relative hidden transition bg-white shadow-lg rounded-2xl p-14 shadow-zinc-700/10 ring-1 ring-zinc-700/10"
class="relative hidden transition bg-white shadow-lg rounded-2xl p-6 md:p-14 shadow-zinc-700/10 ring-1 ring-zinc-700/10"
>
<div class="absolute top-6 right-5">
<button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
phx-change="validate"
phx-submit="save"
>
<div class="flex space-x-2">
<div class="flex flex-col space-x-0 space-y-2 md:space-y-0 md:space-x-2 md:flex-row">
<.input type="date" field={{f, :delivery_date}} label="Delivery Date" />
<.input type="time" field={{f, :start_time}} label="Start" />
<.input type="time" field={{f, :end_time}} label="End" />
Expand Down
6 changes: 2 additions & 4 deletions lib/bike_brigade_web/live/itinerary_live/index.html.heex
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<nav
class="flex items-end justify-between px-4 py-3 mb-1 border-b-2 border-gray-200"
class="flex items-end justify-between px-4 py-3 border-b-2 border-gray-200 mb-4"
aria-label="Pagination"
>
<div class="items-center block font-medium xl:flex">
Expand Down Expand Up @@ -45,8 +45,7 @@
</div>
</nav>
<%= if @campaign_riders != [] do %>
<%= for cr <- @campaign_riders do %>
<div class="flex w-full bg-white shadow sm:my-1 sm:rounded-md">
<div :for={cr <- @campaign_riders} class="flex w-full bg-white shadow mb-2 md:mb-4 sm:rounded-md">
<ul role="list" class="w-full divide-y divide-gray-200">
<li id={"campaign-#{cr.campaign.id}"}>
<div class="px-4 py-4">
Expand Down Expand Up @@ -95,7 +94,6 @@
</li>
</ul>
</div>
<% end %>
<% else %>
<div class="py-4 pl-4">No campaigns found for this day.</div>
<% end %>
10 changes: 6 additions & 4 deletions lib/bike_brigade_web/live/program_live/form_component.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,10 @@
</:actions>
</.header>

<div :for={{s, i} <- Enum.with_index(inputs_for(c, :schedules))} class="flex space-x-2">
<div :for={{s, i} <- Enum.with_index(inputs_for(c, :schedules))} class="flex flex-col space-x-0 space-y-2 md:flex-row md:items-center md:space-y-1 md:space-x-2">
<.input
type="select"
class="mt-8"
field={{s, :weekday}}
options={[
Monday: :monday,
Expand All @@ -52,17 +53,18 @@
/>
<.input type="time" field={{s, :start_time}} />
<.input type="time" field={{s, :end_time}} />
<div class="justify-center ml-auto">
<div class="justify-center mt-1 ml-auto">
<.button
color={:clear}
size={:xxsmall}
size={:xsmall}
phx-click={JS.push("remove_schedule", value: %{index: i}, target: @myself)}
type="button"
>
<span class="sr-only">Close</span>
<span class="md:hidden mr-2 text-gray-700">Remove Schedule</span>
<Heroicons.x_mark solid class="w-6 h-6" />
</.button>
</div>
<hr class="mb-2 md:hidden"/>
</div>
</div>

Expand Down
92 changes: 59 additions & 33 deletions lib/bike_brigade_web/live/rider_live/form_component.ex
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,22 @@ defmodule BikeBrigadeWeb.RiderLive.FormComponent do
belongs_to :location, Location, on_replace: :update
end

def changeset(form, attrs \\ %{}) do
form
|> cast(attrs, [
:name,
:pronouns,
:email,
:phone,
:capacity,
:max_distance,
:last_safety_check,
:internal_notes,
:text_based_itinerary,
:tags
])
|> cast_embed(:flags)
@shared_permitted_keys [
:name,
:pronouns,
:email,
:phone,
:capacity,
:max_distance
]

@doc """
Dispatchers can edit a rider in their entirety; a rider can edit a
subsection of their profile. We handle both cases here by matching on what
the action is for the page.
"""
def changeset(form, action, attrs \\ %{}) do
changeset_impl(form, action, attrs)
|> cast_assoc(:location, with: &Location.geocoding_changeset/2)
|> validate_required([
:name,
Expand All @@ -56,6 +57,22 @@ defmodule BikeBrigadeWeb.RiderLive.FormComponent do
])
end

# `:edit` - the dispatcher is editing the rider
def changeset_impl(form, :edit, attrs) do
form
|> cast(
attrs,
@shared_permitted_keys() ++
[:last_safety_check, :internal_notes, :text_based_itinerary, :tags]
)
|> cast_embed(:flags)
end

# `:edit_profile` - the rider is editing their own profile.
def changeset_impl(form, :edit_profile, attrs) do
form |> cast(attrs, @shared_permitted_keys())
end

def from_rider(%Rider{} = rider) do
map =
rider
Expand All @@ -72,9 +89,9 @@ defmodule BikeBrigadeWeb.RiderLive.FormComponent do
|> Map.update!(:flags, &Map.from_struct/1)
end

def update_form(%__MODULE__{} = form, params) do
def update_form(%__MODULE__{} = form, action, params) do
form
|> changeset(params)
|> changeset(action, params)
|> apply_action(:save)
end
end
Expand All @@ -83,7 +100,7 @@ defmodule BikeBrigadeWeb.RiderLive.FormComponent do
def update(%{rider: rider} = assigns, socket) do
rider = rider |> Repo.preload(:tags)
form = RiderForm.from_rider(rider)
changeset = RiderForm.changeset(form)
changeset = RiderForm.changeset(form, assigns.action)

{:ok,
socket
Expand All @@ -95,12 +112,12 @@ defmodule BikeBrigadeWeb.RiderLive.FormComponent do

@impl true
def handle_event("validate", %{"rider_form" => rider_form_params}, socket) do
case RiderForm.update_form(socket.assigns.form, rider_form_params) do
case RiderForm.update_form(socket.assigns.form, socket.assigns.action, rider_form_params) do
{:ok, form} ->
{:noreply,
socket
|> assign(:form, form)
|> assign(:changeset, RiderForm.changeset(form))}
|> assign(:changeset, RiderForm.changeset(form, socket.assigns.action))}

{:error, changeset} ->
{:noreply, assign(socket, :changeset, changeset)}
Expand Down Expand Up @@ -128,19 +145,11 @@ defmodule BikeBrigadeWeb.RiderLive.FormComponent do
end

defp save_rider(socket, :edit, rider_form_params) do
rider_form_params = Map.merge(%{"tags" => []}, rider_form_params)
with {:ok, form} <-
RiderForm.update_form(socket.assigns.form, rider_form_params),
params = RiderForm.to_params(form),
{:ok, _rider} <-
Riders.update_rider_with_tags(socket.assigns.rider, params, params[:tags]) do
{:noreply,
socket
|> put_flash(:info, "Rider updated successfully")
|> push_navigate(to: socket.assigns.navigate)}
else
_ -> {:noreply, assign(socket, :changeset, socket.assigns.changeset)}
end
save_rider_edit_impl(socket, rider_form_params)
end

defp save_rider(socket, :edit_profile, rider_form_params) do
save_rider_edit_impl(socket, rider_form_params)
end

defp save_rider(socket, :new, rider_params) do
Expand All @@ -155,4 +164,21 @@ defmodule BikeBrigadeWeb.RiderLive.FormComponent do
{:noreply, assign(socket, changeset: changeset)}
end
end

defp save_rider_edit_impl(socket, rider_form_params) do
rider_form_params = Map.merge(%{"tags" => []}, rider_form_params)

with {:ok, form} <-
RiderForm.update_form(socket.assigns.form, socket.assigns.action, rider_form_params),
params = RiderForm.to_params(form),
{:ok, _rider} <-
Riders.update_rider_with_tags(socket.assigns.rider, params, params[:tags]) do
{:noreply,
socket
|> put_flash(:info, "Rider updated successfully")
|> push_navigate(to: socket.assigns.navigate)}
else
_ -> {:noreply, assign(socket, :changeset, socket.assigns.changeset)}
end
end
end
Loading

0 comments on commit bdf9951

Please sign in to comment.