forked from shibao/cannery
add range mode
This commit is contained in:
90
lib/cannery_web/components/add_shot_group_component.ex
Normal file
90
lib/cannery_web/components/add_shot_group_component.ex
Normal file
@ -0,0 +1,90 @@
|
||||
defmodule CanneryWeb.Components.AddShotGroupComponent do
|
||||
@moduledoc """
|
||||
Livecomponent that can create a ShotGroup
|
||||
"""
|
||||
|
||||
use CanneryWeb, :live_component
|
||||
alias Cannery.{Accounts.User, ActivityLog, ActivityLog.ShotGroup, Ammo.AmmoGroup}
|
||||
alias Phoenix.LiveView.Socket
|
||||
|
||||
@impl true
|
||||
@spec update(
|
||||
%{
|
||||
required(:current_user) => User.t(),
|
||||
required(:ammo_group) => AmmoGroup.t(),
|
||||
optional(any()) => any()
|
||||
},
|
||||
Socket.t()
|
||||
) :: {:ok, Socket.t()}
|
||||
def update(%{ammo_group: _ammo_group, current_user: _current_user} = assigns, socket) do
|
||||
changeset =
|
||||
%ShotGroup{date: NaiveDateTime.utc_now(), count: 1} |> ActivityLog.change_shot_group()
|
||||
|
||||
{:ok, socket |> assign(assigns) |> assign(:changeset, changeset)}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_event(
|
||||
"validate",
|
||||
%{"shot_group" => shot_group_params},
|
||||
%{
|
||||
assigns: %{
|
||||
ammo_group: %AmmoGroup{id: ammo_group_id} = ammo_group,
|
||||
current_user: %User{id: user_id}
|
||||
}
|
||||
} = socket
|
||||
) do
|
||||
shot_group_params =
|
||||
shot_group_params
|
||||
|> process_params(ammo_group)
|
||||
|> Map.merge(%{"ammo_group_id" => ammo_group_id, "user_id" => user_id})
|
||||
|
||||
changeset =
|
||||
%ShotGroup{}
|
||||
|> ActivityLog.change_shot_group(shot_group_params)
|
||||
|> Map.put(:action, :validate)
|
||||
|
||||
{:noreply, socket |> assign(:changeset, changeset)}
|
||||
end
|
||||
|
||||
def handle_event(
|
||||
"save",
|
||||
%{"shot_group" => shot_group_params},
|
||||
%{
|
||||
assigns: %{
|
||||
ammo_group: %{id: ammo_group_id} = ammo_group,
|
||||
current_user: %{id: user_id} = current_user,
|
||||
return_to: return_to
|
||||
}
|
||||
} = socket
|
||||
) do
|
||||
socket =
|
||||
shot_group_params
|
||||
|> process_params(ammo_group)
|
||||
|> Map.merge(%{"ammo_group_id" => ammo_group_id, "user_id" => user_id})
|
||||
|> ActivityLog.create_shot_group(current_user, ammo_group)
|
||||
|> case do
|
||||
{:ok, _shot_group} ->
|
||||
prompt = dgettext("prompts", "Shots recorded successfully")
|
||||
socket |> put_flash(:info, prompt) |> push_redirect(to: return_to)
|
||||
|
||||
{:error, %Ecto.Changeset{} = changeset} ->
|
||||
socket |> assign(changeset: changeset)
|
||||
end
|
||||
|
||||
{:noreply, socket}
|
||||
end
|
||||
|
||||
# calculate count from shots left
|
||||
defp process_params(params, %AmmoGroup{count: count}) do
|
||||
new_count =
|
||||
if params |> Map.get("ammo_left", "0") == "" do
|
||||
"0"
|
||||
else
|
||||
params |> Map.get("ammo_left", "0")
|
||||
end
|
||||
|> String.to_integer()
|
||||
|
||||
params |> Map.put("count", count - new_count)
|
||||
end
|
||||
end
|
@ -0,0 +1,47 @@
|
||||
<div>
|
||||
<h2 class="text-center title text-xl text-primary-500">
|
||||
<%= gettext("Record shots") %>
|
||||
</h2>
|
||||
|
||||
<.form
|
||||
let={f}
|
||||
for={@changeset}
|
||||
id="shot-group-form"
|
||||
class="grid grid-cols-3 justify-center items-center space-y-4"
|
||||
phx-target={@myself}
|
||||
phx-change="validate"
|
||||
phx-submit="save"
|
||||
>
|
||||
<%= unless @changeset.valid? do %>
|
||||
<div class="invalid-feedback col-span-3 text-center">
|
||||
<%= changeset_errors(@changeset) %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= label(f, :ammo_left, gettext("Rounds left"), class: "title text-lg text-primary-500") %>
|
||||
<%= number_input(f, :ammo_left,
|
||||
min: 0,
|
||||
max: @ammo_group.count - 1,
|
||||
placeholder: 0,
|
||||
class: "input input-primary col-span-2"
|
||||
) %>
|
||||
<%= error_tag(f, :ammo_left, "col-span-3") %>
|
||||
|
||||
<%= label(f, :notes, gettext("Notes"), class: "title text-lg text-primary-500") %>
|
||||
<%= textarea(f, :notes,
|
||||
class: "input input-primary col-span-2",
|
||||
placeholder: "Really great weather",
|
||||
phx_hook: "MaintainAttrs"
|
||||
) %>
|
||||
<%= error_tag(f, :notes, "col-span-3") %>
|
||||
|
||||
<%= label(f, :date, gettext("Date (UTC)"), class: "title text-lg text-primary-500") %>
|
||||
<%= date_input(f, :date, class: "input input-primary col-span-2") %>
|
||||
<%= error_tag(f, :notes, "col-span-3") %>
|
||||
|
||||
<%= submit(dgettext("actions", "Save"),
|
||||
class: "mx-auto btn btn-primary col-span-3",
|
||||
phx_disable_with: dgettext("prompts", "Saving...")
|
||||
) %>
|
||||
</.form>
|
||||
</div>
|
@ -42,6 +42,12 @@ defmodule CanneryWeb.Components.AmmoGroupCard do
|
||||
</span>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<%= if assigns |> Map.has_key?(:inner_block) do %>
|
||||
<div class="mt-4 flex space-x-4 justify-center items-center">
|
||||
<%= render_slot(@inner_block) %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
@ -55,6 +55,12 @@ defmodule CanneryWeb.Components.Topbar do
|
||||
to: Routes.ammo_group_index_path(Endpoint, :index)
|
||||
) %>
|
||||
</li>
|
||||
<li>
|
||||
<%= link(gettext("Range"),
|
||||
class: "hover:underline",
|
||||
to: Routes.range_index_path(Endpoint, :index)
|
||||
) %>
|
||||
</li>
|
||||
<%= if @current_user.role == :admin do %>
|
||||
<li>
|
||||
<%= link(gettext("Invites"),
|
||||
|
Reference in New Issue
Block a user