diff --git a/assets/css/core_components.css b/assets/css/core_components.css index 7776721..9772f70 100644 --- a/assets/css/core_components.css +++ b/assets/css/core_components.css @@ -255,10 +255,13 @@ } .back-nav-link { - font-size: 0.875rem; - line-height: 1.25rem; - font-weight: 600; - line-height: 1.5rem; + display: flex; + gap: 8px; +} + +.back-nav-link svg { + flex-shrink: 0; + width: 16px; } .table-container { diff --git a/lib/comfycamp/note.ex b/lib/comfycamp/note.ex index 3042fcb..e9e8f3c 100644 --- a/lib/comfycamp/note.ex +++ b/lib/comfycamp/note.ex @@ -1,18 +1,39 @@ -defmodule Comfycamp.Note do - use Ecto.Schema - import Ecto.Changeset +defmodule Comfycamp.Notes do + @moduledoc """ + The Notes context. + """ - schema "notes" do - field :title, :string - field :markdown, :string + import Ecto.Query, warn: false + alias Comfycamp.Repo + alias Comfycamp.Notes.Note - timestamps(type: :utc_datetime) + def change_note(%Note{} = note, attrs \\ %{}) do + note + |> Note.changeset(attrs) end - @doc false - def changeset(note, attrs) do + def create_note(attrs \\ %{}) do + %Note{} + |> Note.changeset(attrs) + |> Repo.insert() + end + + def update_note(%Note{} = note, attrs \\ %{}) do note - |> cast(attrs, [:title, :markdown]) - |> validate_required([:title, :markdown]) + |> Note.changeset(attrs) + |> Repo.update() + end + + def delete_note(%Note{} = note) do + Repo.delete(note) + end + + def get_note!(id) do + Note + |> Repo.get!(id) + end + + def list_notes() do + Repo.all(Note) end end diff --git a/lib/comfycamp/notes/note.ex b/lib/comfycamp/notes/note.ex new file mode 100644 index 0000000..63c9a9b --- /dev/null +++ b/lib/comfycamp/notes/note.ex @@ -0,0 +1,18 @@ +defmodule Comfycamp.Notes.Note do + use Ecto.Schema + import Ecto.Changeset + + schema "notes" do + field :title, :string + field :markdown, :string + + timestamps(type: :utc_datetime) + end + + @doc false + def changeset(note, attrs) do + note + |> cast(attrs, [:title, :markdown]) + |> validate_required([:title, :markdown]) + end +end diff --git a/lib/comfycamp_web/components/core_components.ex b/lib/comfycamp_web/components/core_components.ex index ec3df42..a6d82e1 100644 --- a/lib/comfycamp_web/components/core_components.ex +++ b/lib/comfycamp_web/components/core_components.ex @@ -313,8 +313,7 @@ defmodule ComfycampWeb.CoreComponents do def error(assigns) do ~H"""

- <.icon name="hero-exclamation-circle-mini" class="mt-0.5 h-5 w-5 flex-none" /> - <%= render_slot(@inner_block) %> + <.exclamation_circle_icon /> <%= render_slot(@inner_block) %>

""" end @@ -461,10 +460,9 @@ defmodule ComfycampWeb.CoreComponents do def back(assigns) do ~H""" -
+
<.link navigate={@navigate} class="back-nav-link"> - <.icon name="hero-arrow-left-solid" class="h-3 w-3" /> - <%= render_slot(@inner_block) %> + <.arrow_left_icon /> <%= render_slot(@inner_block) %>
""" diff --git a/lib/comfycamp_web/components/icons/arrow_left_icon.svg.heex b/lib/comfycamp_web/components/icons/arrow_left_icon.svg.heex new file mode 100644 index 0000000..2587149 --- /dev/null +++ b/lib/comfycamp_web/components/icons/arrow_left_icon.svg.heex @@ -0,0 +1,10 @@ + + + diff --git a/lib/comfycamp_web/components/layouts/admin.html.heex b/lib/comfycamp_web/components/layouts/admin.html.heex index f0a86ba..96fd2a6 100644 --- a/lib/comfycamp_web/components/layouts/admin.html.heex +++ b/lib/comfycamp_web/components/layouts/admin.html.heex @@ -2,15 +2,15 @@
-

Comfycamp - админка

<.link href={~p"/"}> Главная страница +

Панель администратора

  • - <.link href={~p"/admin/posts"}> - Посты + <.link href={~p"/admin/notes"}> + Заметки
  • diff --git a/lib/comfycamp_web/controllers/notes_controller.ex b/lib/comfycamp_web/controllers/notes_controller.ex new file mode 100644 index 0000000..71066c8 --- /dev/null +++ b/lib/comfycamp_web/controllers/notes_controller.ex @@ -0,0 +1,89 @@ +defmodule ComfycampWeb.NotesController do + use ComfycampWeb, :controller + + alias Comfycamp.Notes + alias Comfycamp.Notes.Note + + def index(conn, _params) do + notes = Notes.list_notes() + + conn + |> put_layout(html: :admin) + |> render(:index, page_title: "Заметки", notes: notes) + end + + def new(conn, _params) do + changeset = Notes.change_note(%Note{}) + + conn + |> put_layout(html: :admin) + |> render(:new, page_title: "Новая заметка", changeset: changeset) + end + + def edit(conn, %{"id" => id}) do + note = Notes.get_note!(id) + + changeset = Notes.change_note(note) + + conn + |> put_layout(html: :admin) + |> render(:edit, page_title: "Редактировать заметку", changeset: changeset) + end + + def create(conn, %{"note" => note_params}) do + case Notes.create_note(note_params) do + {:ok, note} -> + conn + |> put_flash(:info, "Заметка сохранена.") + |> redirect(to: ~p"/admin/notes/#{note}") + + {:error, changeset} -> + conn + |> put_flash(:error, "Ошибка при обновлении заметки.") + |> put_layout(html: :admin) + |> render(:new, page_title: "Создать заметку", changeset: changeset) + end + end + + def update(conn, %{"id" => id, "note" => note_params}) do + note = Notes.get_note!(id) + + case Notes.update_note(note, note_params) do + {:ok, note} -> + conn + |> put_flash(:info, "Заметка обновлена.") + |> redirect(to: ~p"/admin/notes/#{note}") + + {:error, changeset} -> + conn + |> put_flash(:error, "Ошибка при обновлении заметки.") + |> put_layout(html: :admin) + |> render(:edit, page_title: "Редактировать заметку", changeset: changeset) + end + end + + def show(conn, %{"id" => id}) do + note = Notes.get_note!(id) + + conn + |> put_layout(html: :admin) + |> render(:show, page_title: "Заметка", note: note) + end + + def delete(conn, %{"id" => id}) do + note = Notes.get_note!(id) + + case Notes.delete_note(note) do + {:ok, _note} -> + conn + |> put_flash(:info, "Заметка удалена.") + |> redirect(to: ~p"/admin/notes") + + {:error, changeset} -> + conn + |> put_flash(:error, "Ошибка при удалении заметки.") + |> put_layout(html: :admin) + |> render(:edit, page_title: "Редактировать заметку", changeset: changeset) + end + end +end diff --git a/lib/comfycamp_web/controllers/notes_html.ex b/lib/comfycamp_web/controllers/notes_html.ex new file mode 100644 index 0000000..844d46a --- /dev/null +++ b/lib/comfycamp_web/controllers/notes_html.ex @@ -0,0 +1,5 @@ +defmodule ComfycampWeb.NotesHTML do + use ComfycampWeb, :html + + embed_templates "notes_html/*" +end diff --git a/lib/comfycamp_web/controllers/notes_html/edit.html.heex b/lib/comfycamp_web/controllers/notes_html/edit.html.heex new file mode 100644 index 0000000..42601b8 --- /dev/null +++ b/lib/comfycamp_web/controllers/notes_html/edit.html.heex @@ -0,0 +1,4 @@ +
    +

    Редактировать заметку

    + <.note_form changeset={@changeset} action={~p"/admin/notes/#{@changeset.data.id}"} /> +
    diff --git a/lib/comfycamp_web/controllers/notes_html/index.html.heex b/lib/comfycamp_web/controllers/notes_html/index.html.heex new file mode 100644 index 0000000..2fefb6d --- /dev/null +++ b/lib/comfycamp_web/controllers/notes_html/index.html.heex @@ -0,0 +1,17 @@ +
    + <.link href={~p"/admin/notes/new"}> + Создать заметку + + +
      + <%= for note <- @notes do %> +
    • + <.link href={~p"/admin/notes/#{note}"}> + <%= note.title %> + + + <%= note.updated_at %> +
    • + <% end %> +
    +
    diff --git a/lib/comfycamp_web/controllers/notes_html/new.html.heex b/lib/comfycamp_web/controllers/notes_html/new.html.heex new file mode 100644 index 0000000..a56a22b --- /dev/null +++ b/lib/comfycamp_web/controllers/notes_html/new.html.heex @@ -0,0 +1,4 @@ +
    +

    Новая заметка

    + <.note_form changeset={@changeset} action={~p"/admin/notes"} /> +
    diff --git a/lib/comfycamp_web/controllers/notes_html/note_form.html.heex b/lib/comfycamp_web/controllers/notes_html/note_form.html.heex new file mode 100644 index 0000000..35d5c83 --- /dev/null +++ b/lib/comfycamp_web/controllers/notes_html/note_form.html.heex @@ -0,0 +1,18 @@ +<.simple_form :let={f} for={@changeset} action={@action}> + <.input field={f[:title]} type="text" label="Заголовок" /> + <.input field={f[:markdown]} type="textarea" label="Содержание (markdown)" /> + + <:actions> + <.button>Сохранить + + + +<%= if @changeset.data.id do %> + <.link + href={~p"/admin/notes/#{@changeset.data}"} + method="DELETE" + data-confirm="Вы уверены?" + > + Удалить + +<% end %> diff --git a/lib/comfycamp_web/controllers/notes_html/show.html.heex b/lib/comfycamp_web/controllers/notes_html/show.html.heex new file mode 100644 index 0000000..bba0bdf --- /dev/null +++ b/lib/comfycamp_web/controllers/notes_html/show.html.heex @@ -0,0 +1,13 @@ +
    + <.back navigate={~p"/admin/notes"}>Назад +

    <%= @note.title %>

    + + <.link href={~p"/admin/notes/#{@note}/edit"}> + Редактировать + + +

    Создана: <%= @note.inserted_at %>

    +

    Обновлена: <%= @note.updated_at %>

    + +
    <%= @note.markdown %>
    +
    diff --git a/lib/comfycamp_web/router.ex b/lib/comfycamp_web/router.ex index 3942437..9bf3aa1 100644 --- a/lib/comfycamp_web/router.ex +++ b/lib/comfycamp_web/router.ex @@ -89,8 +89,8 @@ defmodule ComfycampWeb.Router do pipe_through [:browser, :require_authenticated_user, :ensure_admin] get "/", AdminPageController, :home - get "/posts", AdminPageController, :posts get "/users", AdminPageController, :users get "/services", AdminPageController, :services + resources "/notes", NotesController end end