Split logic in multiple components

This commit is contained in:
2024-10-17 23:02:08 +02:00
parent e3093c99c7
commit ad12768ccf
8 changed files with 122 additions and 83 deletions

View File

@@ -0,0 +1,34 @@
defmodule MihainatorWeb.FileInputComponent do
@moduledoc false
use Phoenix.LiveComponent
@impl true
def mount(socket) do
{:ok,
socket
|> assign(:submit_disabled?, true)
|> allow_upload(:history, accept: ~w(.csv))}
end
@impl true
def handle_event("validate", _params, socket) do
{:noreply,
socket
|> assign(:submit_disabled?, false)}
end
@impl true
def handle_event("save", _params, socket) do
consume_uploaded_entries(socket, :history, fn %{path: path}, _entry ->
Task.async(fn -> Mihainator.Extractor.extract(path) end)
{:ok, nil}
end)
{:noreply, socket}
end
defp error_to_string(:too_large), do: "Too large"
defp error_to_string(:not_accepted), do: "You have selected an unacceptable file type"
end

View File

@@ -0,0 +1,56 @@
<div>
<p class="text-lg">Upload a Threema chat history file (.csv) and see who's more interactive!</p>
<form
id="upload-form"
phx-submit="save"
phx-change="validate"
phx-target={@myself}
class="flex flex-col space-y-4"
>
<div>
<label class="block mb-2 text-sm font-bold text-gray-900" for={@uploads.history.ref}>
CSV file
</label>
<.live_file_input
upload={@uploads.history}
class="block w-full text-sm text-gray-900 border border-gray-300 rounded-lg cursor-pointer bg-gray-50 dark:text-gray-400 focus:outline-none dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400"
/>
</div>
<button
:if={@submit_disabled?}
disabled={@submit_disabled?}
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded w-1/2 place-self-end disabled:opacity-75"
type="submit"
>
Upload
</button>
<button
:if={not @submit_disabled?}
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded w-1/2 place-self-end"
type="submit"
>
Upload
</button>
</form>
<%= for entry <- @uploads.history.entries do %>
<article class="upload-entry">
<%!-- Phoenix.Component.upload_errors/2 returns a list of error atoms --%>
<%= for err <- upload_errors(@uploads.history, entry) do %>
<p class="alert alert-danger"><%= error_to_string(err) %></p>
<% end %>
</article>
<% end %>
<%!-- use phx-drop-target with the upload ref to enable file drag and drop --%>
<section phx-drop-target={@uploads.history.ref}>
<%!-- Phoenix.Component.upload_errors/1 returns a list of error atoms --%>
<%= for err <- upload_errors(@uploads.history) do %>
<p class="alert alert-danger"><%= error_to_string(err) %></p>
<% end %>
</section>
</div>

View File

@@ -0,0 +1,17 @@
defmodule MihainatorWeb.ResultComponent do
@moduledoc false
use Phoenix.LiveComponent
@impl true
def update(assigns, socket) do
socket = assign(socket, assigns)
{:ok, socket}
end
@impl true
def mount(socket) do
{:ok, socket}
end
end

View File

@@ -1,6 +1,4 @@
<div class="flex flex-col space-y-8">
<h1 class="text-5xl">Threema history checker</h1>
<p class="text-lg">This is the result of your history:</p>
<div class="calendar-wrapper">

View File

@@ -1,8 +0,0 @@
defmodule MihainatorWeb.ResultLive do
use MihainatorWeb, :live_view
@impl Phoenix.LiveView
def mount(_params, _session, socket) do
{:ok, socket}
end
end

View File

@@ -1,30 +1,13 @@
defmodule MihainatorWeb.UploadLive do
@moduledoc false
use MihainatorWeb, :live_view
@impl Phoenix.LiveView
def mount(_params, _session, socket) do
{:ok,
socket
|> assign(:submit_disabled?, true)
|> allow_upload(:history, accept: ~w(.csv))}
end
@impl Phoenix.LiveView
def handle_event("validate", _params, socket) do
{:noreply,
socket
|> assign(:submit_disabled?, false)}
end
@impl Phoenix.LiveView
def handle_event("save", _params, socket) do
consume_uploaded_entries(socket, :history, fn %{path: path}, _entry ->
Task.async(fn -> Mihainator.Extractor.extract(path) end)
{:ok, nil}
end)
{:noreply, socket}
|> assign(:has_result, false)}
end
@impl Phoenix.LiveView
@@ -32,11 +15,8 @@ defmodule MihainatorWeb.UploadLive do
def handle_info({ref, result}, socket) do
Process.demonitor(ref, [:flush])
socket = assign(socket, :calendar_dates, result)
socket = assign(socket, calendar_dates: result, has_result: true)
{:noreply, push_navigate(socket, to: ~p"/result")}
{:noreply, socket}
end
defp error_to_string(:too_large), do: "Too large"
defp error_to_string(:not_accepted), do: "You have selected an unacceptable file type"
end

View File

@@ -1,52 +1,14 @@
<div class="flex flex-col space-y-8">
<h1 class="text-5xl">Threema history checker</h1>
<p class="text-lg">Upload a Threema chat history file (.csv) and see who's more interactive!</p>
<form id="upload-form" phx-submit="save" phx-change="validate" class="flex flex-col space-y-4">
<div>
<label class="block mb-2 text-sm font-bold text-gray-900" for={@uploads.history.ref}>
CSV file
</label>
<.live_file_input
upload={@uploads.history}
class="block w-full text-sm text-gray-900 border border-gray-300 rounded-lg cursor-pointer bg-gray-50 dark:text-gray-400 focus:outline-none dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400"
<%!-- <.live_component module={MihainatorWeb.UserComponent} id="user" /> --%>
<%= if @has_result == false do %>
<.live_component module={MihainatorWeb.FileInputComponent} id="file-input" />
<% else %>
<.live_component
module={MihainatorWeb.ResultComponent}
id="result"
calendar_dates={@calendar_dates}
/>
</div>
<button
:if={@submit_disabled?}
disabled={@submit_disabled?}
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded w-1/2 place-self-end disabled:opacity-75"
type="submit"
>
Upload
</button>
<button
:if={not @submit_disabled?}
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded w-1/2 place-self-end"
type="submit"
>
Upload
</button>
</form>
<%= for entry <- @uploads.history.entries do %>
<article class="upload-entry">
<%!-- Phoenix.Component.upload_errors/2 returns a list of error atoms --%>
<%= for err <- upload_errors(@uploads.history, entry) do %>
<p class="alert alert-danger"><%= error_to_string(err) %></p>
<% end %>
</article>
<% end %>
<%!-- use phx-drop-target with the upload ref to enable file drag and drop --%>
<section phx-drop-target={@uploads.history.ref}>
<%!-- Phoenix.Component.upload_errors/1 returns a list of error atoms --%>
<%= for err <- upload_errors(@uploads.history) do %>
<p class="alert alert-danger"><%= error_to_string(err) %></p>
<% end %>
</section>
<% end %>
</div>

View File

@@ -18,8 +18,8 @@ defmodule MihainatorWeb.Router do
pipe_through :browser
get "/", PageController, :home
live "/upload", UploadLive
live "/result", ResultLive
end
# Other scopes may use custom stacks.