diff --git a/lib/philomena/forums/forum.ex b/lib/philomena/forums/forum.ex index eb58d50e..eda67fd1 100644 --- a/lib/philomena/forums/forum.ex +++ b/lib/philomena/forums/forum.ex @@ -28,5 +28,7 @@ defmodule Philomena.Forums.Forum do |> cast(attrs, [:name, :short_name, :description, :access_level]) |> validate_required([:name, :short_name, :description, :access_level]) |> validate_inclusion(:access_level, ~W(normal assistant staff)) + |> validate_format(:short_name, ~r/\A[a-z]+\z/, message: "must consist only of lowercase letters") + |> unique_constraint(:short_name, name: :index_forums_on_short_name) end -end \ No newline at end of file +end diff --git a/lib/philomena_web/controllers/admin/forum_controller.ex b/lib/philomena_web/controllers/admin/forum_controller.ex new file mode 100644 index 00000000..4bb8413e --- /dev/null +++ b/lib/philomena_web/controllers/admin/forum_controller.ex @@ -0,0 +1,54 @@ +defmodule PhilomenaWeb.Admin.ForumController do + use PhilomenaWeb, :controller + + alias Philomena.Forums.Forum + alias Philomena.Forums + + plug :verify_authorized + plug :load_resource, model: Forum, id_field: "short_name" + + def index(conn, _params) do + render(conn, "index.html") + end + + def new(conn, _params) do + changeset = Forums.change_forum(%Forum{}) + render(conn, "new.html", changeset: changeset) + end + + def create(conn, %{"forum" => forum_params}) do + case Forums.create_forum(forum_params) do + {:ok, forum} -> + conn + |> put_flash(:info, "Forum created successfully.") + |> redirect(to: Routes.admin_forum_path(conn, :index)) + + {:error, changeset} -> + render(conn, "new.html", changeset: changeset) + end + end + + def edit(conn, _params) do + changeset = Forums.change_forum(conn.assigns.forum) + render(conn, "edit.html", changeset: changeset) + end + + def update(conn, %{"forum" => forum_params}) do + case Forums.update_forum(conn.assigns.forum, forum_params) do + {:ok, forum} -> + conn + |> put_flash(:info, "Forum updated successfully.") + |> redirect(to: Routes.admin_forum_path(conn, :index)) + + {:error, changeset} -> + render(conn, "edit.html", changeset: changeset) + end + end + + defp verify_authorized(conn, _opts) do + case Canada.Can.can?(conn.assigns.current_user, :edit, Forum) do + true -> conn + _false -> PhilomenaWeb.NotAuthorizedPlug.call(conn) + end + end +end diff --git a/lib/philomena_web/router.ex b/lib/philomena_web/router.ex index fc4ef7a9..f9ba1738 100644 --- a/lib/philomena_web/router.ex +++ b/lib/philomena_web/router.ex @@ -201,6 +201,8 @@ defmodule PhilomenaWeb.Router do resources "/site_notices", SiteNoticeController, except: [:show] resources "/adverts", AdvertController, except: [:show] + + resources "/forums", ForumController, except: [:show, :delete] end resources "/duplicate_reports", DuplicateReportController, only: [] do diff --git a/lib/philomena_web/templates/admin/forum/_form.html.slime b/lib/philomena_web/templates/admin/forum/_form.html.slime new file mode 100644 index 00000000..4e6465b8 --- /dev/null +++ b/lib/philomena_web/templates/admin/forum/_form.html.slime @@ -0,0 +1,26 @@ += form_for @changeset, @action, fn f -> + = if @changeset.action do + .alert.alert-danger + p Oops, something went wrong! Please check the errors below. + + .field + => label f, :name, "Name:" + = text_input f, :name, class: "input input--wide" + = error_tag f, :name + + .field + => label f, :short_name, "Slug:" + = text_input f, :short_name, class: "input input--wide" + = error_tag f, :short_name + + .field + => label f, :description, "Description:" + = textarea f, :description, class: "input input--wide" + = error_tag f, :description + + .field + => label f, :access_level, "Access level:" + = select f, :access_level, ["normal", "assistant", "staff"], class: "input" + = error_tag f, :access_level + + = submit "Save Forum", class: "button" diff --git a/lib/philomena_web/templates/admin/forum/edit.html.slime b/lib/philomena_web/templates/admin/forum/edit.html.slime new file mode 100644 index 00000000..4f513a09 --- /dev/null +++ b/lib/philomena_web/templates/admin/forum/edit.html.slime @@ -0,0 +1,5 @@ +h2 Edit Forum + += render "_form.html", Map.put(assigns, :action, Routes.admin_forum_path(@conn, :update, @forum)) + += link "Back", to: Routes.admin_forum_path(@conn, :index) diff --git a/lib/philomena_web/templates/admin/forum/index.html.slime b/lib/philomena_web/templates/admin/forum/index.html.slime new file mode 100644 index 00000000..fec3c55c --- /dev/null +++ b/lib/philomena_web/templates/admin/forum/index.html.slime @@ -0,0 +1,17 @@ +h2 Listing Forums + +table.table + thead + tr + th Name + th Options + tbody + = for forum <- @forums do + tr + td + = link forum.name, to: Routes.forum_path(@conn, :show, forum) + + td class="text-right" + = link "Edit", to: Routes.admin_forum_path(@conn, :edit, forum) + += link "New Forum", to: Routes.admin_forum_path(@conn, :new) diff --git a/lib/philomena_web/templates/admin/forum/new.html.slime b/lib/philomena_web/templates/admin/forum/new.html.slime new file mode 100644 index 00000000..2d6fd0cd --- /dev/null +++ b/lib/philomena_web/templates/admin/forum/new.html.slime @@ -0,0 +1,5 @@ +h2 New Forum + += render "_form.html", Map.put(assigns, :action, Routes.admin_forum_path(@conn, :create)) + += link "Back", to: Routes.admin_forum_path(@conn, :index) diff --git a/lib/philomena_web/views/admin/forum_view.ex b/lib/philomena_web/views/admin/forum_view.ex new file mode 100644 index 00000000..f159d522 --- /dev/null +++ b/lib/philomena_web/views/admin/forum_view.ex @@ -0,0 +1,3 @@ +defmodule PhilomenaWeb.Admin.ForumView do + use PhilomenaWeb, :view +end