118 lines
3.7 KiB
Elixir
118 lines
3.7 KiB
Elixir
defmodule FirehoseWeb.EditorDashboardLive do
|
|
use FirehoseWeb, :live_view
|
|
|
|
alias Blogex.Post
|
|
|
|
@impl true
|
|
def mount(_params, _session, socket) do
|
|
all_posts = Blogex.Registry.all_posts_unfiltered()
|
|
|
|
drafts =
|
|
all_posts
|
|
|> Enum.filter(&(Post.visibility(&1) == :draft))
|
|
|> Enum.sort_by(& &1.date, {:desc, Date})
|
|
|
|
scheduled =
|
|
all_posts
|
|
|> Enum.filter(&(Post.visibility(&1) == :scheduled))
|
|
|> Enum.sort_by(& &1.date, {:asc, Date})
|
|
|
|
{:ok,
|
|
socket
|
|
|> assign(:page_title, "Editor Dashboard")
|
|
|> assign(:drafts, drafts)
|
|
|> assign(:scheduled, scheduled)
|
|
|> assign(:active_tab, :drafts)}
|
|
end
|
|
|
|
@impl true
|
|
def render(assigns) do
|
|
~H"""
|
|
<div class="max-w-4xl mx-auto">
|
|
<h1 class="text-2xl font-bold mb-6">Dashboard</h1>
|
|
|
|
<div class="flex gap-4 mb-6 border-b border-zinc-200">
|
|
<button
|
|
phx-click="switch_tab"
|
|
phx-value-tab="drafts"
|
|
class={[
|
|
"pb-2 px-1 text-sm font-medium transition-colors",
|
|
if(@active_tab == :drafts,
|
|
do: "border-b-2 border-zinc-900 text-zinc-900",
|
|
else: "text-zinc-500 hover:text-zinc-700"
|
|
)
|
|
]}
|
|
>
|
|
Drafts ({length(@drafts)})
|
|
</button>
|
|
<button
|
|
phx-click="switch_tab"
|
|
phx-value-tab="scheduled"
|
|
class={[
|
|
"pb-2 px-1 text-sm font-medium transition-colors",
|
|
if(@active_tab == :scheduled,
|
|
do: "border-b-2 border-zinc-900 text-zinc-900",
|
|
else: "text-zinc-500 hover:text-zinc-700"
|
|
)
|
|
]}
|
|
>
|
|
Scheduled ({length(@scheduled)})
|
|
</button>
|
|
</div>
|
|
|
|
<div id="drafts-tab" class={if(@active_tab != :drafts, do: "hidden")}>
|
|
<div :if={@drafts == []} class="text-zinc-500 text-sm">No drafts</div>
|
|
<div :for={post <- @drafts} class="py-4 border-b border-zinc-100 last:border-0">
|
|
<div class="flex items-center justify-between">
|
|
<div>
|
|
<.link
|
|
navigate={post_path(post)}
|
|
class="text-base font-medium text-zinc-900 hover:underline"
|
|
>
|
|
{post.title}
|
|
</.link>
|
|
<div class="text-sm text-zinc-500 mt-1">
|
|
{post.author} · {Calendar.strftime(post.date, "%b %d, %Y")} ·
|
|
<span class="text-amber-600 font-medium">Draft</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="scheduled-tab" class={if(@active_tab != :scheduled, do: "hidden")}>
|
|
<div :if={@scheduled == []} class="text-zinc-500 text-sm">No scheduled posts</div>
|
|
<div :for={post <- @scheduled} class="py-4 border-b border-zinc-100 last:border-0">
|
|
<div class="flex items-center justify-between">
|
|
<div>
|
|
<.link
|
|
navigate={post_path(post)}
|
|
class="text-base font-medium text-zinc-900 hover:underline"
|
|
>
|
|
{post.title}
|
|
</.link>
|
|
<div class="text-sm text-zinc-500 mt-1">
|
|
{post.author} · {Calendar.strftime(post.date, "%b %d, %Y")} ·
|
|
<span class="text-blue-600 font-medium">
|
|
{Post.days_until_live(post)} days until live
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
"""
|
|
end
|
|
|
|
@impl true
|
|
def handle_event("switch_tab", %{"tab" => tab}, socket) do
|
|
{:noreply, assign(socket, :active_tab, String.to_existing_atom(tab))}
|
|
end
|
|
|
|
defp post_path(post) do
|
|
blog = Blogex.Registry.get_blog!(post.blog)
|
|
"#{blog.base_path()}/#{post.id}"
|
|
end
|
|
end
|