devel #73
13 changed files with 166 additions and 75 deletions
|
@ -278,6 +278,17 @@ defmodule Chiya.Notes do
|
||||||
Repo.delete(note_tag)
|
Repo.delete(note_tag)
|
||||||
end
|
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
|
def create_note_comment(attrs \\ %{}) do
|
||||||
%NoteComment{}
|
%NoteComment{}
|
||||||
|> NoteComment.changeset(attrs)
|
|> NoteComment.changeset(attrs)
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
<header class="px-4 sm:px-6 lg:px-8">
|
<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 justify-end border-b border-gray-300 dark:border-gray-800 py-3">
|
||||||
<div class="flex items-center gap-4">
|
<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
|
<.link
|
||||||
href={~p"/admin/notes"}
|
href={~p"/admin/notes"}
|
||||||
class="text-xs font-semibold leading-6 text-gray-900 hover:text-gray-700 dark:text-gray-200"
|
class="text-xs font-semibold leading-6 text-gray-900 hover:text-gray-700 dark:text-gray-200"
|
||||||
|
|
|
@ -6,6 +6,8 @@ defmodule ChiyaWeb.PublicComponents do
|
||||||
router: ChiyaWeb.Router,
|
router: ChiyaWeb.Router,
|
||||||
statics: ChiyaWeb.static_paths()
|
statics: ChiyaWeb.static_paths()
|
||||||
|
|
||||||
|
import ChiyaWeb.Format
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Renders a horizontal line
|
Renders a horizontal line
|
||||||
"""
|
"""
|
||||||
|
@ -46,4 +48,66 @@ defmodule ChiyaWeb.PublicComponents do
|
||||||
</header>
|
</header>
|
||||||
"""
|
"""
|
||||||
end
|
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
|
end
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
<:item title="Content"><%= @channel.content %></:item>
|
<:item title="Content"><%= @channel.content %></:item>
|
||||||
<:item title="Visibility"><%= @channel.visibility %></:item>
|
<:item title="Visibility"><%= @channel.visibility %></:item>
|
||||||
<:item title="Slug"><%= @channel.slug %></:item>
|
<:item title="Slug"><%= @channel.slug %></:item>
|
||||||
|
<:item title="Layout"><%= @channel.layout %></:item>
|
||||||
</.list>
|
</.list>
|
||||||
|
|
||||||
<.back navigate={~p"/admin/channels"}>Back to channels</.back>
|
<.back navigate={~p"/admin/channels"}>Back to channels</.back>
|
||||||
|
|
|
@ -1,11 +1,19 @@
|
||||||
defmodule ChiyaWeb.CommentController do
|
defmodule ChiyaWeb.CommentController do
|
||||||
use ChiyaWeb, :controller
|
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
|
def create(conn, %{"slug" => note_slug, "note_comment" => comment_params}) do
|
||||||
note = Chiya.Notes.get_note_by_slug_preloaded!(note_slug)
|
note = Chiya.Notes.get_note_by_slug_preloaded!(note_slug)
|
||||||
|
|
||||||
IO.inspect(comment_params)
|
|
||||||
|
|
||||||
case Chiya.Notes.create_note_comment(comment_params) do
|
case Chiya.Notes.create_note_comment(comment_params) do
|
||||||
{:ok, _comment} ->
|
{:ok, _comment} ->
|
||||||
redirect(conn, to: ~p"/#{note_slug}?error=0")
|
redirect(conn, to: ~p"/#{note_slug}?error=0")
|
||||||
|
|
25
lib/chiya_web/controllers/comment_html/index.html.heex
Normal file
25
lib/chiya_web/controllers/comment_html/index.html.heex
Normal 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>
|
22
lib/chiya_web/controllers/comment_html/show.html.heex
Normal file
22
lib/chiya_web/controllers/comment_html/show.html.heex
Normal 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>
|
|
@ -7,14 +7,6 @@
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="w-full mt-6 sm:w-auto flex flex-col gap-1.5">
|
<div class="w-full mt-6 sm:w-auto flex flex-col gap-1.5">
|
||||||
<%= for note <- @channel.notes do %>
|
<.note_list notes={@channel.notes} layout={@channel.layout} />
|
||||||
<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 %>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -23,55 +23,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<%= if @channel do %>
|
<%= if @channel do %>
|
||||||
<%= if @channel.layout == :default do %>
|
<.note_list notes={@channel.notes} layout={@channel.layout} />
|
||||||
<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 %>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -82,5 +82,4 @@
|
||||||
<.button>Submit Comment</.button>
|
<.button>Submit Comment</.button>
|
||||||
</:actions>
|
</:actions>
|
||||||
</.simple_form>
|
</.simple_form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -15,6 +15,12 @@
|
||||||
<.input field={f[:custom_css]} type="textarea" label="Custom css" class="font-mono" />
|
<.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[: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[:home_channel_id]} type="select" label="Home Channel" options={@channels} />
|
||||||
|
<.input
|
||||||
|
field={f[:default_channel_id]}
|
||||||
|
type="select"
|
||||||
|
label="Default Channel"
|
||||||
|
options={@channels}
|
||||||
|
/>
|
||||||
<:actions>
|
<:actions>
|
||||||
<.button>Save Setting</.button>
|
<.button>Save Setting</.button>
|
||||||
</:actions>
|
</:actions>
|
||||||
|
|
|
@ -31,6 +31,11 @@
|
||||||
<:item title="User agent"><%= @setting.user_agent %></:item>
|
<:item title="User agent"><%= @setting.user_agent %></:item>
|
||||||
<:item title="Custom css"><%= @setting.custom_css %></:item>
|
<:item title="Custom css"><%= @setting.custom_css %></:item>
|
||||||
<:item title="Custom html"><%= @setting.custom_html %></: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>
|
</.list>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
@ -60,6 +60,7 @@ defmodule ChiyaWeb.Router do
|
||||||
resources "/notes", NoteController, except: [:show]
|
resources "/notes", NoteController, except: [:show]
|
||||||
resources "/settings", SettingController, singleton: true
|
resources "/settings", SettingController, singleton: true
|
||||||
resources "/identities", IdentityController
|
resources "/identities", IdentityController
|
||||||
|
resources "/comments", CommentController, only: [:index, :show]
|
||||||
|
|
||||||
get "/notes/import", NoteController, :import_prepare
|
get "/notes/import", NoteController, :import_prepare
|
||||||
post "/notes/import", NoteController, :import_run
|
post "/notes/import", NoteController, :import_run
|
||||||
|
|
Loading…
Reference in a new issue