defmodule AshHqWeb.Pages.Ashley do
@moduledoc "Ashley page"
use Surface.LiveComponent
import AshHqWeb.Tails
alias Phoenix.LiveView.JS
alias Surface.Components.Form
alias Surface.Components.Form.{
Field,
TextArea,
TextInput
}
prop(current_user, :any)
prop(params, :map)
data(messages, :list)
data(message_form, :any)
data(new_message_form, :any)
data(conversation, :any)
data(conversations, :list)
data(editing_conversation, :boolean)
data(conversation_form, :any)
def render(assigns) do
~F"""
{#if is_nil(@current_user) || !@current_user.ashley_access}
You do not have access to this page.
{#else}
New
{#for conversation <- @conversations}
{/for}
{#for conversation <- @conversations}
{/for}
{#if @conversation}
{#if @editing_conversation}
{#else}
{/if}
{#else}
{/if}
{/if}
"""
end
def update(assigns, socket) do
{:ok,
socket
|> assign(assigns)
|> assign(editing_conversation: false)
|> assign_conversations()
|> assign_conversation()
|> assign_message_form()
|> assign_change_name_form()
|> assign_new_message_form}
end
defp assign_change_name_form(socket) do
if socket.assigns[:conversation] do
assign(
socket,
:conversation_form,
AshPhoenix.Form.for_update(socket.assigns.conversation, :update,
actor: socket.assigns.current_user,
api: AshHq.Ashley,
as: "conversation"
)
)
else
assign(socket, conversation_form: nil)
end
end
defp assign_conversations(socket) do
if socket.assigns[:current_user] do
assign(socket,
conversations:
AshHq.Ashley.Conversation.read!(
actor: socket.assigns.current_user,
load: :question_count
)
)
else
assign(socket, conversations: [])
end
end
defp assign_conversation(socket) do
if socket.assigns[:current_user] && socket.assigns[:params]["conversation_id"] do
assign(socket,
conversation:
Enum.find(
socket.assigns.conversations,
&(&1.id == socket.assigns[:params]["conversation_id"])
)
|> AshHq.Ashley.load!(:questions, actor: socket.assigns.current_user)
)
else
assign(socket, :conversation, nil)
end
end
defp assign_message_form(socket) do
if socket.assigns[:current_user] && socket.assigns[:conversation] do
assign(
socket,
:message_form,
AshPhoenix.Form.for_create(AshHq.Ashley.Question, :ask,
actor: socket.assigns[:current_user],
api: AshHq.Ashley,
as: "message",
prepare_source: fn changeset ->
Ash.Changeset.force_change_attribute(
changeset,
:conversation_id,
socket.assigns.conversation.id
)
end
)
)
else
assign(socket, :message_form, nil)
end
end
defp assign_new_message_form(socket) do
if socket.assigns[:current_user] do
assign(
socket,
:new_message_form,
AshPhoenix.Form.for_create(AshHq.Ashley.Question, :ask,
actor: socket.assigns[:current_user],
api: AshHq.Ashley,
as: "new_message"
)
)
else
assign(socket, :new_message_form, nil)
end
end
def handle_event("save_conversation", %{"conversation" => conversation_params}, socket) do
case AshPhoenix.Form.submit(socket.assigns.conversation_form, params: conversation_params) do
{:ok, _message} ->
{:noreply,
socket
|> assign_conversations()
|> assign_conversation()
|> assign(editing_conversation: false)
|> assign_message_form()}
{:error, form} ->
{:noreply, assign(socket, conversation_form: form)}
end
end
def handle_event("save_message", %{"message" => message_params}, socket) do
case AshPhoenix.Form.submit(socket.assigns.message_form, params: message_params) do
{:ok, _message} ->
{:noreply,
socket
|> assign_conversations()
|> assign_conversation()
|> assign_message_form()}
{:error, form} ->
{:noreply, assign(socket, message_form: form)}
end
end
def handle_event("save_new_message", %{"new_message" => message_params}, socket) do
case AshPhoenix.Form.submit(socket.assigns.new_message_form, params: message_params) do
{:ok, message} ->
{:noreply,
socket
|> push_patch(to: "/ashley/#{message.conversation_id}")}
{:error, form} ->
{:noreply, assign(socket, message_form: form)}
end
end
def handle_event("toggle-editing-conversation", _, socket) do
{:noreply, assign(socket, editing_conversation: true)}
end
def handle_event("destroy-conversation", %{"conversation-id" => conversation_id}, socket) do
case Enum.split_with(socket.assigns.conversations, &(&1.id == conversation_id)) do
{[conversation], rest} ->
AshHq.Ashley.Conversation.destroy!(conversation, actor: socket.assigns.current_user)
{:noreply, assign(socket, conversations: rest, conversation: nil)}
_ ->
{:noreply, socket}
end
end
end