defmodule GorgonWeb.HuskLive.FormComponent do
use GorgonWeb, :live_component
alias Gorgon.Forge.Husk
@impl true
def render(assigns) do
~H"""
<div>
<.header>
<%= @title %>
<:subtitle>
{{copy}}
</:subtitle>
</.header>
<.simple_form
for={@form}
id="husk-form"
phx-target={@myself}
phx-change="validate"
phx-submit="save"
>
<.input field={@form[:name]} label="Name" />
<.input field={@form[:twitch_user]} label="Twitch user" />
<p>
Go
<.a _target="blank" navigate="https://twitchapps.com/tmi/">here</.a>
while logged in with your husk's account to get an oauth token.
</p>
<.input field={@form[:twitch_pass]} label="Oauth token" />
<!-- <.live_component
module={GorgonWeb.HuskLive.StringArrayComponent}
id={@husk.id || :new}
rows={@form.data.twitch_channels}
husk={@husk}
current_user={@current_user}
/>
-->
<label class="block text-sm font-semibold leading-6 text-purble-800 dark:text-purble-200">
Twitch channels <%= @hideaddbutton %>
</label>
<%= if AshPhoenix.Form.value(@form, :twitch_channels) != nil do %>
<%= for {channel, index} <- Enum.with_index(AshPhoenix.Form.value(@form, :twitch_channels)) do %>
<div class="flex !mt-0">
<.input phx-value-index={index} required name="form[twitch_channels][]" value={channel} />
<.button
type="button"
class={[
"mt-2 ml-2 px-2 bg-transparent text-red-500 hover:bg-red-500 hover:text-white",
@hidedeletebutton && "hidden"
]}
phx-click="delete_channel"
phx-value-index={index}
phx-target={@myself}
>
<.icon name="hero-x-circle"></.icon>
</.button>
</div>
<% end %>
<% else %>
its nil!!!
<% end %>
<.button
class={["!mt-2", @hideaddbutton && "hidden"]}
type="button"
phx-click="add_channel"
phx-target={@myself}
>
add channel
</.button>
<:actions>
<.button phx-disable-with="Saving...">Save Husk</.button>
</:actions>
</.simple_form>
</div>
"""
end
@impl true
def handle_event("delete_channel", %{"index" => index}, socket) do
# TODO: dont let the last one get deleted
IO.inspect(socket.assigns.form.params)
new_form =
AshPhoenix.Form.update_form(socket.assigns.form.source, "form", fn child_form ->
new_value =
AshPhoenix.Form.value(socket.assigns.form, :twitch_channels)
|> List.delete_at(String.to_integer(index))
AshPhoenix.Form.validate(
socket.assigns.form,
Map.put(AshPhoenix.Form.params(socket.assigns.form), "twitch_channels", new_value)
)
end)
socket =
socket
|> assign(:form, new_form)
|> assign(hideaddbutton: hideaddbutton?(AshPhoenix.Form.params(new_form)))
|> assign(hidedeletebutton: hidedeletebutton?(AshPhoenix.Form.params(new_form)))
{:noreply, socket}
end
@impl true
def handle_event("add_channel", %{}, socket) do
new_form =
AshPhoenix.Form.update_form(socket.assigns.form.source, "form", fn child_form ->
case AshPhoenix.Form.value(socket.assigns.form, :twitch_channels) do
nil ->
new_value = [""]
AshPhoenix.Form.validate(
socket.assigns.form,
Map.put(AshPhoenix.Form.params(socket.assigns.form), "twitch_channels", new_value)
)
_ ->
new_value = AshPhoenix.Form.value(socket.assigns.form, :twitch_channels) ++ [""]
AshPhoenix.Form.validate(
socket.assigns.form,
Map.put(AshPhoenix.Form.params(socket.assigns.form), "twitch_channels", new_value)
)
end
end)
socket =
socket
|> assign(:form, new_form)
|> assign(hideaddbutton: true)
|> assign(hidedeletebutton: false)
{:noreply, socket}
end
# like mount but for livecomponents its called update??
@impl true
def update(assigns, socket) do
# form =
# AshPhoenix.Form.for_action(Husk, assigns.action, api: Husk)
# |> to_form()
form = actionify_form(assigns)
IO.inspect(form)
IO.inspect(form.data)
IO.inspect(Map.from_struct(form.data))
socket =
socket
|> assign(assigns)
|> assign(form: form)
|> assign(hideaddbutton: false)
|> assign(hidedeletebutton: false)
# trying to make it not show delete if there's only one entry on first mount
# |> assign(hidedeletebutton: hidedeletebutton?(Map.from_struct(form.data)))
{:ok, socket}
end
defp actionify_form(assigns) do
case assigns.action do
:new ->
AshPhoenix.Form.for_create(Husk, :create,
api: Gorgon.Forge,
actor: assigns.current_user
)
|> to_form()
:edit ->
AshPhoenix.Form.for_update(assigns.husk, :update,
api: Gorgon.Forge,
actor: assigns.current_user
)
|> to_form
end
end
@impl true
def handle_event("validate", %{"form" => husk_params}, socket) do
form = socket.assigns.form |> AshPhoenix.Form.validate(husk_params)
socket = socket |> assign(form: form) |> assign(hideaddbutton: hideaddbutton?(husk_params))
{:noreply, socket}
end
defp hideaddbutton?(husk_params) do
IO.inspect(husk_params)
case husk_params["twitch_channels"] do
[] ->
false
_ ->
if husk_params["twitch_channels"] |> List.last() == "" ||
husk_params["twitch_channels"] |> List.last() == nil do
true
else
false
end
end
end
defp hidedeletebutton?(params) do
if length(params["twitch_channels"]) < 2 do
true
end
end
def handle_event("save", %{"form" => form}, socket) do
save_husk(socket, socket.assigns.action, form)
end
# save a new
defp save_husk(socket, :new, params) do
form = AshPhoenix.Form.validate(socket.assigns.form, params)
case AshPhoenix.Form.submit(form) do
{:ok, husk} ->
notify_parent({:saved, husk})
{:noreply,
socket
|> put_flash(:info, "Husk created successfully")
# socket.assigns.patch)}
|> push_navigate(to: ~p"/husks/#{husk}")}
{:error, form} ->
{:noreply, assign(socket, form)}
other ->
IO.inspect(other, label: "other")
end
end
# save a edit
defp save_husk(socket, :edit, params) do
form = AshPhoenix.Form.validate(socket.assigns.form, params)
case AshPhoenix.Form.submit(form) do
{:ok, husk} ->
notify_parent({:saved, husk})
{:noreply,
socket
|> put_flash(:info, "Husk updated successfully")
|> push_patch(to: socket.assigns.patch)}
{:error, form} ->
{:noreply, assign(socket, form)}
end
end
defp notify_parent(msg), do: send(self(), {__MODULE__, msg})
end