devel #73

Merged
inhji merged 7 commits from devel into main 2023-05-09 16:26:15 +02:00
13 changed files with 166 additions and 75 deletions

View file

@ -278,6 +278,17 @@ defmodule Chiya.Notes do
Repo.delete(note_tag)
end
def list_note_comments() do
NoteComment
|> order_by(:inserted_at)
|> Repo.all()
|> Repo.preload(:note)
end
def get_note_comment!(id) do
Repo.get!(NoteComment, id) |> Repo.preload(:note)
end
def create_note_comment(attrs \\ %{}) do
%NoteComment{}
|> NoteComment.changeset(attrs)

View file

@ -1,6 +1,12 @@
<header class="px-4 sm:px-6 lg:px-8">
<div class="flex items-center justify-end border-b border-gray-300 dark:border-gray-800 py-3">
<div class="flex items-center gap-4">
<.link
href={~p"/admin/comments"}
class="text-xs font-semibold leading-6 text-gray-900 hover:text-gray-700 dark:text-gray-200"
>
<.icon name="hero-document-text" class="w-4 h-4" /> Comments
</.link>
<.link
href={~p"/admin/notes"}
class="text-xs font-semibold leading-6 text-gray-900 hover:text-gray-700 dark:text-gray-200"

View file

@ -6,6 +6,8 @@ defmodule ChiyaWeb.PublicComponents do
router: ChiyaWeb.Router,
statics: ChiyaWeb.static_paths()
import ChiyaWeb.Format
@doc """
Renders a horizontal line
"""
@ -46,4 +48,66 @@ defmodule ChiyaWeb.PublicComponents do
</header>
"""
end
attr :layout, :atom, default: :list
attr :notes, :list, required: true
def note_list(assigns) do
case assigns.layout do
:gallery ->
~H"""
<section class="note-list gallery | mt-6">
<%= for note <- assigns.notes do %>
<article>
<section class="flex flex-wrap justify-start gap-3">
<%= for image <- note.images do %>
<a
href={ChiyaWeb.Uploaders.NoteImage.url({image.path, image}, :full_dithered)}
class="lightbox | w-28"
data-gallery={gallery_name(note)}
data-description={ChiyaWeb.Markdown.render(image.content)}
>
<img
src={ChiyaWeb.Uploaders.NoteImage.url({image.path, image}, :thumb_dithered)}
loading="lazy"
/>
</a>
<% end %>
</section>
<a
href={~p"/#{note.slug}"}
class="text-theme-primary text-lg/10 font-semibold rounded-lg -mx-2 -my-0.5 px-2 py-0.5 hover:bg-theme-primary/10 transition"
>
<%= note.name %>
<span class="text-theme-muted font-normal text-sm">
<%= pretty_date(note.published_at) %>
</span>
</a>
</article>
<.line />
<% end %>
</section>
"""
_ ->
~H"""
<section class="default | mt-6 sm:w-auto flex flex-col gap-1.5">
<%= for note <- assigns.notes do %>
<a
href={~p"/#{note.slug}"}
class="rounded-lg -mx-2 -my-0.5 px-2 py-0.5 hover:bg-theme-primary/10 transition"
>
<span class="text-theme-primary text-lg font-semibold leading-8">
<%= note.name %>
</span>
<span class="text-theme-base text-sm"><%= pretty_date(note.published_at) %></span>
</a>
<% end %>
</section>
"""
end
end
defp gallery_name(note), do: "gallery-#{note.id}"
end

View file

@ -16,6 +16,7 @@
<:item title="Content"><%= @channel.content %></:item>
<:item title="Visibility"><%= @channel.visibility %></:item>
<:item title="Slug"><%= @channel.slug %></:item>
<:item title="Layout"><%= @channel.layout %></:item>
</.list>
<.back navigate={~p"/admin/channels"}>Back to channels</.back>

View file

@ -1,11 +1,19 @@
defmodule ChiyaWeb.CommentController do
use ChiyaWeb, :controller
def index(conn, _params) do
comments = Chiya.Notes.list_note_comments()
render(conn, comments: comments)
end
def show(conn, %{"id" => comment_id}) do
comment = Chiya.Notes.get_note_comment!(comment_id)
render(conn, comment: comment)
end
def create(conn, %{"slug" => note_slug, "note_comment" => comment_params}) do
note = Chiya.Notes.get_note_by_slug_preloaded!(note_slug)
IO.inspect(comment_params)
case Chiya.Notes.create_note_comment(comment_params) do
{:ok, _comment} ->
redirect(conn, to: ~p"/#{note_slug}?error=0")

View file

@ -0,0 +1,25 @@
<.header>
<.icon name="hero-document-text" /> Comments
<:subtitle>Comments are attached to notes</:subtitle>
</.header>
<.table id="comments" rows={@comments} row_click={&JS.navigate(~p"/admin/comments/#{&1}")}>
<:col :let={comment} label="Author"><%= comment.author_name %></:col>
<:col :let={comment} label="Inserted at"><%= from_now(comment.inserted_at) %></:col>
<:col :let={comment} label="Approved at"><%= from_now(comment.approved_at) %></:col>
<:action :let={comment}>
<div class="sr-only">
<.link navigate={~p"/admin/comments/#{comment}"}>Show</.link>
</div>
</:action>
<:action :let={comment}>
<.link href={~p"/admin/comments/#{comment}"} method="delete" data-confirm="Are you sure?">
Delete
</.link>
</:action>
<:action :let={comment}>
<div class="sr-only">
<.link navigate={~p"/admin/comments/#{comment}/approve"}>Approve</.link>
</div>
</:action>
</.table>

View file

@ -0,0 +1,22 @@
<.header>
Comment <%= @comment.id %>
<:subtitle>This is a comment record from your database.</:subtitle>
<:actions>
<.link href={~p"/admin/notes/#{@comment}/approve"}>
<.button>Approve note</.button>
</.link>
</:actions>
</.header>
<.list>
<:item title="Name"><%= @comment.author_name %></:item>
<:item title="Content"><%= @comment.content %></:item>
<:item title="Inserted at"><%= @comment.inserted_at %></:item>
<:item title="Approved at"><%= @comment.approved_at %></:item>
<:item title="Kind"><%= @comment.kind %></:item>
<:item title="Note">
<a href={"/admin/notes/#{@comment.note.id}"}><%= @comment.note.name %></a>
</:item>
</.list>
<.back navigate={~p"/admin/comments"}>Back to comments</.back>

View file

@ -7,14 +7,6 @@
</p>
<div class="w-full mt-6 sm:w-auto flex flex-col gap-1.5">
<%= for note <- @channel.notes do %>
<a
href={~p"/#{note.slug}"}
class="rounded -mx-2 -my-0.5 px-2 py-0.5 hover:bg-theme-primary/10 transition"
>
<span class="text-theme-primary text-lg font-semibold leading-8"><%= note.name %></span>
<span class="text-theme-base text-sm"><%= pretty_date(note.published_at) %></span>
</a>
<% end %>
<.note_list notes={@channel.notes} layout={@channel.layout} />
</div>
</div>

View file

@ -23,55 +23,6 @@
</div>
</div>
<%= if @channel do %>
<%= if @channel.layout == :default do %>
<section class="default | mt-6 sm:w-auto flex flex-col gap-1.5">
<%= for note <- @channel.notes do %>
<a
href={~p"/#{note.slug}"}
class="rounded-lg -mx-2 -my-0.5 px-2 py-0.5 hover:bg-theme-primary/10 transition"
>
<span class="text-theme-primary text-lg font-semibold leading-8">
<%= note.name %>
</span>
<span class="text-theme-base text-sm"><%= pretty_date(note.published_at) %></span>
</a>
<% end %>
</section>
<% end %>
<%= if @channel.layout == :gallery do %>
<section class="gallery | mt-6">
<%= for note <- @channel.notes do %>
<article>
<section class="flex flex-wrap justify-start gap-3">
<%= for image <- note.images do %>
<a
href={ChiyaWeb.Uploaders.NoteImage.url({image.path, image}, :full_dithered)}
class="lightbox | w-28"
data-gallery="note"
data-description={ChiyaWeb.Markdown.render(image.content)}
>
<img
src={ChiyaWeb.Uploaders.NoteImage.url({image.path, image}, :thumb_dithered)}
loading="lazy"
/>
</a>
<% end %>
</section>
<a
href={~p"/#{note.slug}"}
class="text-theme-primary text-lg/10 font-semibold rounded-lg -mx-2 -my-0.5 px-2 py-0.5 hover:bg-theme-primary/10 transition"
>
<%= note.name %>
<span class="text-theme-muted font-normal text-sm">
<%= pretty_date(note.published_at) %>
</span>
</a>
</article>
<.line />
<% end %>
</section>
<% end %>
<.note_list notes={@channel.notes} layout={@channel.layout} />
<% end %>
</div>

View file

@ -5,9 +5,9 @@
</h1>
<p class="mt-2 text-sm leading-6 text-theme-base">
<%= if @note.published_at do %>
<span>Published</span>
<span>Published</span>
<% else %>
<span>Unpublished</span>
<span>Unpublished</span>
<% end %>
<time class="text-theme-primary font-semibold"><%= pretty_date(@note.published_at) %></time>
<span>·</span>
@ -55,20 +55,20 @@
<.line />
<h2 class="mb-6 text-theme-base"><%= Enum.count(@note.comments) %> Comments</h2>
<aside id="comments" class="flex flex-col gap-6">
<%= for comment <- @note.comments do %>
<article class="text-theme-base bg-theme-base/10 p-1">
<header class="flex flex-row justify-between">
<strong class="text-theme-primary"><%= comment.author_name %></strong>
<span class="text-theme-dim"><%= from_now(comment.inserted_at) %></span>
</header>
<p><%= comment.content %></p>
</article>
<article class="text-theme-base bg-theme-base/10 p-1">
<header class="flex flex-row justify-between">
<strong class="text-theme-primary"><%= comment.author_name %></strong>
<span class="text-theme-dim"><%= from_now(comment.inserted_at) %></span>
</header>
<p><%= comment.content %></p>
</article>
<% end %>
</aside>
<% end %>
<.line />
<.simple_form :let={f} for={@changeset} action={~p"/#{@note.slug}/comment"}>
@ -76,11 +76,10 @@
Oops, something went wrong! Please check the errors below.
</.error>
<.input field={f[:author_name]} type="text" placeholder="Name" />
<.input field={f[:content]} type="textarea" placeholder="Content" rows="3" />
<.input field={f[:content]} type="textarea" placeholder="Content" rows="3" />
<.input field={f[:note_id]} type="hidden" />
<:actions>
<.button>Submit Comment</.button>
</:actions>
</.simple_form>
</div>

View file

@ -15,6 +15,12 @@
<.input field={f[:custom_css]} type="textarea" label="Custom css" class="font-mono" />
<.input field={f[:custom_html]} type="textarea" label="Custom html" class="font-mono" />
<.input field={f[:home_channel_id]} type="select" label="Home Channel" options={@channels} />
<.input
field={f[:default_channel_id]}
type="select"
label="Default Channel"
options={@channels}
/>
<:actions>
<.button>Save Setting</.button>
</:actions>

View file

@ -31,6 +31,11 @@
<:item title="User agent"><%= @setting.user_agent %></:item>
<:item title="Custom css"><%= @setting.custom_css %></:item>
<:item title="Custom html"><%= @setting.custom_html %></:item>
<:item title="Home Channel"><%= @setting.home_channel_id %></:item>
<:item title="Home Channel">
<%= if @setting.home_channel, do: @setting.home_channel.name %>
</:item>
<:item title="Default Channel">
<%= if @setting.default_channel, do: @setting.default_channel.name %>
</:item>
</.list>
<% end %>

View file

@ -60,6 +60,7 @@ defmodule ChiyaWeb.Router do
resources "/notes", NoteController, except: [:show]
resources "/settings", SettingController, singleton: true
resources "/identities", IdentityController
resources "/comments", CommentController, only: [:index, :show]
get "/notes/import", NoteController, :import_prepare
post "/notes/import", NoteController, :import_run