Skip to content

Commit

Permalink
edit episode
Browse files Browse the repository at this point in the history
  • Loading branch information
sorax committed Aug 26, 2024
1 parent 38a1b48 commit e3f8200
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 84 deletions.
104 changes: 62 additions & 42 deletions lib/radiator_web/live/episode_live/index.ex
Original file line number Diff line number Diff line change
Expand Up @@ -42,25 +42,12 @@ defmodule RadiatorWeb.EpisodeLive.Index do
end

socket
|> apply_action(socket.assigns.live_action, params)
|> assign(:selected_episode, episode)
|> reply(:noreply)
end

@impl true
def handle_event("new_episode", _params, socket) do
show = socket.assigns.show
number = Podcast.get_next_episode_number(show.id)

episode = %Podcast.Episode{}
changeset = Episode.changeset(episode, %{number: number})

socket
|> assign(:action, :new_episode)
|> assign(:episode, episode)
|> assign(:form, to_form(changeset))
|> reply(:noreply)
end

def handle_event("validate", %{"episode" => params}, socket) do
changeset = Episode.changeset(socket.assigns.episode, params)

Expand All @@ -70,10 +57,9 @@ defmodule RadiatorWeb.EpisodeLive.Index do
end

def handle_event("save", %{"episode" => params}, socket) do
params
|> Map.put("show_id", socket.assigns.show.id)
|> Podcast.create_episode()
|> process_create_episode(socket)
params = Map.put(params, "show_id", socket.assigns.show.id)

save_episode(socket, socket.assigns.action, params)
end

@impl true
Expand Down Expand Up @@ -124,6 +110,64 @@ defmodule RadiatorWeb.EpisodeLive.Index do
|> reply(:noreply)
end

defp apply_action(socket, :new, %{"show" => show_id}) do
number = Podcast.get_next_episode_number(show_id)

episode = %Podcast.Episode{}
changeset = Episode.changeset(episode, %{number: number})

socket
|> assign(:title, "New Episode")
|> assign(:episode, episode)
|> assign(:form, to_form(changeset))
end

defp apply_action(socket, :edit, %{"episode" => episode_id}) do
episode = Podcast.get_episode!(episode_id)
changeset = Podcast.change_episode(episode, %{})

socket
|> assign(:title, "Edit Episode")
|> assign(:episode, episode)
|> assign(:form, to_form(changeset))
end

defp apply_action(socket, :index, _params) do
socket
end

defp save_episode(socket, :new, params) do
case Podcast.create_episode(params) do
{:ok, episode} ->
NodeRepository.create_node(%{
"uuid" => Ecto.UUID.generate(),
"creator_id" => socket.assigns.current_user.id,
"episode_id" => episode.id
})

socket
|> put_flash(:info, "Episode created")
|> push_patch(to: ~p"/admin/podcast/#{socket.assigns.show}/#{episode}")
|> reply(:noreply)

{:error, %Ecto.Changeset{} = changeset} ->
socket |> assign(form: to_form(changeset)) |> reply(:noreply)
end
end

defp save_episode(socket, :edit, params) do
case Podcast.update_episode(socket.assigns.episode, params) do
{:ok, episode} ->
socket
|> put_flash(:info, "Episode updated")
|> push_patch(to: ~p"/admin/podcast/#{socket.assigns.show}/#{episode}")
|> reply(:noreply)

{:error, %Ecto.Changeset{} = changeset} ->
socket |> assign(form: to_form(changeset)) |> reply(:noreply)
end
end

defp get_selected_episode(%{"episode" => episode_id}) do
Podcast.get_episode!(episode_id)
end
Expand All @@ -143,28 +187,4 @@ defmodule RadiatorWeb.EpisodeLive.Index do
socket
|> stream_insert(:event_logs, event, at: 0)
end

defp process_create_episode({:ok, episode}, socket) do
show = Podcast.get_show!(socket.assigns.show.id, preload: :episodes)

NodeRepository.create_node(%{
"uuid" => Ecto.UUID.generate(),
"creator_id" => socket.assigns.current_user.id,
"episode_id" => episode.id
})

socket
|> assign(:action, nil)
|> assign(:episodes, show.episodes)
|> put_flash(:info, "Episode created successfully")
|> push_navigate(to: ~p"/admin/podcast/#{show}/#{episode}")
|> reply(:noreply)
end

defp process_create_episode({:error, %Ecto.Changeset{} = changeset}, socket) do
socket
|> assign(:form, to_form(changeset))
|> put_flash(:info, "Episode could not be created")
|> reply(:noreply)
end
end
40 changes: 28 additions & 12 deletions lib/radiator_web/live/episode_live/index.html.heex
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
<div class="grid grid-cols-12 gap-24">
<aside class="col-span-12 sm:col-span-4">
<button
:if={@action != :new_episode}
class="block w-full my-4 rounded text-white bg-[#df7366] px-8 py-2"
phx-click="new_episode"
<.link
patch={~p"/admin/podcast/#{@show}/new"}
class="block w-full my-4 rounded text-white bg-[#df7366] px-8 py-2 text-center"
>
Create Episode
</button>
</.link>

<ol>
<li
Expand All @@ -23,28 +22,45 @@
</aside>

<div class="col-span-12 sm:col-span-8">
<section :if={@action == :new_episode}>
<section :if={@live_action in [:new, :edit]}>
<div class="p-4 my-4 bg-[#f0f4f4]">
<h3 class="text-xl">Create Episode</h3>
<h3 class="text-xl"><%= @title %></h3>
<.form :let={f} for={@form} id="episode-form" phx-change="validate" phx-submit="save">
<.input field={f[:number]} type="text" label="Number" />
<.input field={f[:title]} type="text" label="Title" />
<div class="flex items-center justify-between gap-6 mt-2">
<div
<.link
patch={~p"/admin/podcast/#{@show}"}
class="px-3 py-2 text-sm font-semibold leading-6 border rounded-lg cursor-pointer phx-submit-loading:opacity-75 border-zinc-900 hover:border-zinc-700 text-zinc-900 active:text-zinc-900/80"
phx-click="cancel"
>
Cancel
</div>
</.link>
<.button phx-disable-with="Saving...">Save Episode</.button>
</div>
</.form>
</div>
</section>

<section :if={@selected_episode}>
<h2 class="text-2xl"><%= @selected_episode.number %> <%= @selected_episode.title %></h2>
<img class="my-4" src={~p"/images/pic06.jpg"} alt="" />
<.header class="text-2xl">
<%= @selected_episode.number %>: <%= @selected_episode.title %>
<:actions>
<.link
navigate={~p"/admin/podcast/#{@show}/#{@selected_episode}/edit"}
class="flex gap-4 my-4"
>
<.icon name="hero-pencil-square" class="w-5 h-5" />
</.link>
<.link
title="Delete"
phx-click={JS.push("delete", value: %{id: @selected_episode.id})}
data-confirm="Are you sure?"
>
<.icon name="hero-trash" class="w-5 h-5" />
</.link>
</:actions>
</.header>

<.live_component
id="outline"
module={RadiatorWeb.OutlineComponent}
Expand Down
3 changes: 3 additions & 0 deletions lib/radiator_web/live/outline_component.ex
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,14 @@ defmodule RadiatorWeb.OutlineComponent do

def update(%{episode_id: id} = assigns, socket) do
nodes = get_nodes(id)
# node_forms = Enum.map(nodes, &to_change_form(&1, %{}))

socket
|> assign(assigns)
|> stream_configure(:nodes, dom_id: &"outline-node-#{&1.uuid}")
|> stream(:nodes, nodes)
# |> stream_configure(:nodes_new, dom_id: &"outline-node-#{&1.uuid}")
# |> stream(:nodes_new, node_forms)
|> reply(:ok)
end

Expand Down
80 changes: 68 additions & 12 deletions lib/radiator_web/live/outline_component.html.heex
Original file line number Diff line number Diff line change
@@ -1,13 +1,67 @@
<div id={@id} class="my-6" phx-hook="outline" phx-update="stream">
<div id={"#{@id}-nodes"} class="nodes">
<div
:for={{id, node} <- @streams.nodes}
id={id}
class="item group relative my-1 data-[dirty=true]:bg-red-100"
data-parent={node.parent_id}
data-prev={node.prev_id}
data-collapsed={false}
>
<div id={@id}>
<aside>
<h3 class="text-base font-semibold leading-7 text-gray-600">Shortcuts</h3>
<dl class="divide-y divide-gray-100">
<div class="grid grid-cols-3 gap-4 px-0 py-2">
<dt class="text-sm font-medium leading-6 text-gray-600">Add note</dt>
<dd class="col-span-2 mt-0 text-sm leading-6 text-gray-700">
</dd>
</div>
<div class="grid grid-cols-3 gap-4 px-0 py-2">
<dt class="text-sm font-medium leading-6 text-gray-600">Cursor up</dt>
<dd class="col-span-2 mt-0 text-sm leading-6 text-gray-700">
</dd>
</div>
<div class="grid grid-cols-3 gap-4 px-0 py-2">
<dt class="text-sm font-medium leading-6 text-gray-600">Cursor down</dt>
<dd class="col-span-2 mt-0 text-sm leading-6 text-gray-700">
</dd>
</div>
<div class="grid grid-cols-3 gap-4 px-0 py-2">
<dt class="text-sm font-medium leading-6 text-gray-600">Indent</dt>
<dd class="col-span-2 mt-0 text-sm leading-6 text-gray-700">
</dd>
</div>
<div class="grid grid-cols-3 gap-4 px-0 py-2">
<dt class="text-sm font-medium leading-6 text-gray-600">Outdent</dt>
<dd class="col-span-2 mt-0 text-sm leading-6 text-gray-700">
⇧⇥
</dd>
</div>
<div class="grid grid-cols-3 gap-4 px-0 py-2">
<dt class="text-sm font-medium leading-6 text-gray-600">Collapse</dt>
<dd class="col-span-2 mt-0 text-sm leading-6 text-gray-700"></dd>
</div>
<div class="grid grid-cols-3 gap-4 px-0 py-2">
<dt class="text-sm font-medium leading-6 text-gray-600">Expand</dt>
<dd class="col-span-2 mt-0 text-sm leading-6 text-gray-700"></dd>
</div>
<div class="grid grid-cols-3 gap-4 px-0 py-2">
<dt class="text-sm font-medium leading-6 text-gray-600">Move node up</dt>
<dd class="col-span-2 mt-0 text-sm leading-6 text-gray-700">⌥↑</dd>
</div>
<div class="grid grid-cols-3 gap-4 px-0 py-2">
<dt class="text-sm font-medium leading-6 text-gray-600">Move node down</dt>
<dd class="col-span-2 mt-0 text-sm leading-6 text-gray-700">⌥↓</dd>
</div>
</dl>
</aside>

<div id={@id <> "-stream"} class="my-6" phx-hook="outline" phx-update="stream">
<div id={"#{@id}-nodes"} class="nodes">
<div
:for={{id, node} <- @streams.nodes}
id={id}
class="item group relative my-1 data-[dirty=true]:bg-red-100"
data-parent={node.parent_id}
data-prev={node.prev_id}
data-collapsed={false}
>
<!--
<button class="absolute top-0.5 left-0 group-[.collapsed]:-rotate-90 duration-200 z-10">
<svg
width="20"
Expand All @@ -31,8 +85,10 @@
<circle cx="9" cy="9" r="3.5"></circle>
</svg>
</a>
<div class="ml-10 content" contentEditable><%= node.content %></div>
<div class="ml-4 children group-[.collapsed]:hidden"></div>
-->
<div class="ml-5 content" contentEditable><%= node.content %></div>
<div class="ml-4 children group-[.collapsed]:hidden"></div>
</div>
</div>
</div>
</div>
3 changes: 3 additions & 0 deletions lib/radiator_web/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,10 @@ defmodule RadiatorWeb.Router do
live "/admin/accounts", AccountsLive.Index, :index

live "/admin/podcast/:show", EpisodeLive.Index, :index

live "/admin/podcast/:show/new", EpisodeLive.Index, :new
live "/admin/podcast/:show/:episode", EpisodeLive.Index, :index
live "/admin/podcast/:show/:episode/edit", EpisodeLive.Index, :edit
end
end

Expand Down
22 changes: 4 additions & 18 deletions test/radiator_web/live/episode_live_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -50,25 +50,11 @@ defmodule RadiatorWeb.EpisodeLiveTest do
test "create new episode will create node as well", %{conn: conn, show: show} do
{:ok, live, _html} = live(conn, ~p"/admin/podcast/#{show.id}")

live
|> element(~s{main aside button}, "Create Episode")
|> render_click()
assert live
|> element(~s|aside a:fl-contains("Create Episode")|)
|> render_click() =~ "New Episode"

submit_live =
live
|> form("#episode-form", episode: %{title: "Some new episode"})
|> render_submit()

{path, %{"info" => "Episode created successfully"}} = assert_redirect(live)

_episode_id = path |> Path.basename() |> String.to_integer()

{:ok, new_live, _html} = submit_live |> follow_redirect(conn)

assert new_live |> has_element?(~s{main h2}, "Some new episode")

# assert_push_event(new_live, "list", %{nodes: [node]})
# %{content: nil, parent_id: nil, prev_id: nil, episode_id: ^episode_id} = node
assert_patch(live, ~p"/admin/podcast/#{show.id}/new")
end
end

Expand Down

0 comments on commit e3f8200

Please sign in to comment.