From 5eda2c7156f9b04e16ac33888f0e789221d74bca Mon Sep 17 00:00:00 2001 From: Inhji Date: Tue, 7 Mar 2023 23:05:25 +0100 Subject: [PATCH] add site settings --- lib/chiya/site.ex | 61 +++++++++++++++++++ lib/chiya/site/setting.ex | 25 ++++++++ .../components/layouts/root.html.heex | 8 +++ .../controllers/setting_controller.ex | 48 +++++++++++++++ lib/chiya_web/controllers/setting_html.ex | 13 ++++ .../controllers/setting_html/edit.html.heex | 8 +++ .../controllers/setting_html/new.html.heex | 8 +++ .../setting_html/setting_form.html.heex | 20 ++++++ .../controllers/setting_html/show.html.heex | 28 +++++++++ lib/chiya_web/live/user_settings_live.ex | 6 +- lib/chiya_web/router.ex | 1 + .../20230307204825_create_settings.exs | 16 +++++ test/chiya/site_test.exs | 58 ++++++++++++++++++ .../controllers/setting_controller_test.exs | 61 +++++++++++++++++++ .../user_session_controller_test.exs | 2 +- test/support/fixtures/site_fixtures.ex | 25 ++++++++ 16 files changed, 384 insertions(+), 4 deletions(-) create mode 100644 lib/chiya/site.ex create mode 100644 lib/chiya/site/setting.ex create mode 100644 lib/chiya_web/controllers/setting_controller.ex create mode 100644 lib/chiya_web/controllers/setting_html.ex create mode 100644 lib/chiya_web/controllers/setting_html/edit.html.heex create mode 100644 lib/chiya_web/controllers/setting_html/new.html.heex create mode 100644 lib/chiya_web/controllers/setting_html/setting_form.html.heex create mode 100644 lib/chiya_web/controllers/setting_html/show.html.heex create mode 100644 priv/repo/migrations/20230307204825_create_settings.exs create mode 100644 test/chiya/site_test.exs create mode 100644 test/chiya_web/controllers/setting_controller_test.exs create mode 100644 test/support/fixtures/site_fixtures.ex diff --git a/lib/chiya/site.ex b/lib/chiya/site.ex new file mode 100644 index 0000000..ce1a7e4 --- /dev/null +++ b/lib/chiya/site.ex @@ -0,0 +1,61 @@ +defmodule Chiya.Site do + @moduledoc """ + The Site context. + """ + + import Ecto.Query, warn: false + alias Chiya.Repo + + alias Chiya.Site.Setting + + def get_settings(), do: Repo.one(Setting) + + @doc """ + Creates a setting. + + ## Examples + + iex> create_setting(%{field: value}) + {:ok, %Setting{}} + + iex> create_setting(%{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def create_setting(attrs \\ %{}) do + %Setting{} + |> Setting.changeset(attrs) + |> Repo.insert() + end + + @doc """ + Updates a setting. + + ## Examples + + iex> update_setting(setting, %{field: new_value}) + {:ok, %Setting{}} + + iex> update_setting(setting, %{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def update_setting(%Setting{} = setting, attrs) do + setting + |> Setting.changeset(attrs) + |> Repo.update() + end + + @doc """ + Returns an `%Ecto.Changeset{}` for tracking setting changes. + + ## Examples + + iex> change_setting(setting) + %Ecto.Changeset{data: %Setting{}} + + """ + def change_setting(%Setting{} = setting, attrs \\ %{}) do + Setting.changeset(setting, attrs) + end +end diff --git a/lib/chiya/site/setting.ex b/lib/chiya/site/setting.ex new file mode 100644 index 0000000..90e133e --- /dev/null +++ b/lib/chiya/site/setting.ex @@ -0,0 +1,25 @@ +defmodule Chiya.Site.Setting do + use Ecto.Schema + import Ecto.Changeset + + schema "settings" do + field :title, :string, default: "Title" + field :subtitle, :string, default: "Subtitle" + + field :custom_css, :string, default: "" + field :custom_html, :string, default: "" + + field :theme, Ecto.Enum, values: [:default] + + field :user_agent, :string, default: "Chiya/0.x +https://inhji.de" + + timestamps() + end + + @doc false + def changeset(setting, attrs) do + setting + |> cast(attrs, [:title, :subtitle, :theme, :user_agent, :custom_css, :custom_html]) + |> validate_required([:title, :subtitle, :theme, :user_agent]) + end +end diff --git a/lib/chiya_web/components/layouts/root.html.heex b/lib/chiya_web/components/layouts/root.html.heex index 8dc75d8..0b1b99e 100644 --- a/lib/chiya_web/components/layouts/root.html.heex +++ b/lib/chiya_web/components/layouts/root.html.heex @@ -25,6 +25,14 @@ Profile +
  • + <.link + href={~p"/admin/settings"} + class="text-xs leading-6 text-zinc-100 font-semibold hover:text-zinc-300" + > + Settings + +
  • <.link href={~p"/user/log_out"} diff --git a/lib/chiya_web/controllers/setting_controller.ex b/lib/chiya_web/controllers/setting_controller.ex new file mode 100644 index 0000000..8af9e4c --- /dev/null +++ b/lib/chiya_web/controllers/setting_controller.ex @@ -0,0 +1,48 @@ +defmodule ChiyaWeb.SettingController do + use ChiyaWeb, :controller + + alias Chiya.Site + alias Chiya.Site.Setting + + def new(conn, _params) do + changeset = Site.change_setting(%Setting{}) + render(conn, :new, changeset: changeset) + end + + def create(conn, %{"setting" => setting_params}) do + case Site.create_setting(setting_params) do + {:ok, _setting} -> + conn + |> put_flash(:info, "Setting created successfully.") + |> redirect(to: ~p"/admin/settings") + + {:error, %Ecto.Changeset{} = changeset} -> + render(conn, :new, changeset: changeset) + end + end + + def show(conn, _params) do + setting = Site.get_settings() + render(conn, :show, setting: setting) + end + + def edit(conn, _params) do + setting = Site.get_settings() + changeset = Site.change_setting(setting) + render(conn, :edit, setting: setting, changeset: changeset) + end + + def update(conn, %{"setting" => setting_params}) do + setting = Site.get_settings() + + case Site.update_setting(setting, setting_params) do + {:ok, _setting} -> + conn + |> put_flash(:info, "Setting updated successfully.") + |> redirect(to: ~p"/admin/settings") + + {:error, %Ecto.Changeset{} = changeset} -> + render(conn, :edit, setting: setting, changeset: changeset) + end + end +end diff --git a/lib/chiya_web/controllers/setting_html.ex b/lib/chiya_web/controllers/setting_html.ex new file mode 100644 index 0000000..a1808ef --- /dev/null +++ b/lib/chiya_web/controllers/setting_html.ex @@ -0,0 +1,13 @@ +defmodule ChiyaWeb.SettingHTML do + use ChiyaWeb, :html + + embed_templates "setting_html/*" + + @doc """ + Renders a setting form. + """ + attr :changeset, Ecto.Changeset, required: true + attr :action, :string, required: true + + def setting_form(assigns) +end diff --git a/lib/chiya_web/controllers/setting_html/edit.html.heex b/lib/chiya_web/controllers/setting_html/edit.html.heex new file mode 100644 index 0000000..0c294f3 --- /dev/null +++ b/lib/chiya_web/controllers/setting_html/edit.html.heex @@ -0,0 +1,8 @@ +<.header> + Edit Setting <%= @setting.id %> + <:subtitle>Use this form to manage setting records in your database. + + +<.setting_form changeset={@changeset} action={~p"/admin/settings"} /> + +<.back navigate={~p"/admin/settings"}>Back to settings diff --git a/lib/chiya_web/controllers/setting_html/new.html.heex b/lib/chiya_web/controllers/setting_html/new.html.heex new file mode 100644 index 0000000..e4ba824 --- /dev/null +++ b/lib/chiya_web/controllers/setting_html/new.html.heex @@ -0,0 +1,8 @@ +<.header> + New Setting + <:subtitle>Use this form to manage setting records in your database. + + +<.setting_form changeset={@changeset} action={~p"/admin/settings"} /> + +<.back navigate={~p"/admin/settings"}>Back to settings diff --git a/lib/chiya_web/controllers/setting_html/setting_form.html.heex b/lib/chiya_web/controllers/setting_html/setting_form.html.heex new file mode 100644 index 0000000..248764d --- /dev/null +++ b/lib/chiya_web/controllers/setting_html/setting_form.html.heex @@ -0,0 +1,20 @@ +<.simple_form :let={f} for={@changeset} action={@action}> + <.error :if={@changeset.action}> + Oops, something went wrong! Please check the errors below. + + <.input field={f[:title]} type="text" label="Title" /> + <.input field={f[:subtitle]} type="text" label="Subtitle" /> + <.input + field={f[:theme]} + type="select" + label="Theme" + prompt="Choose a value" + options={Ecto.Enum.values(Chiya.Site.Setting, :theme)} + /> + <.input field={f[:user_agent]} type="text" label="User agent" /> + <.input field={f[:custom_css]} type="text" label="Custom css" /> + <.input field={f[:custom_html]} type="text" label="Custom html" /> + <:actions> + <.button>Save Setting + + diff --git a/lib/chiya_web/controllers/setting_html/show.html.heex b/lib/chiya_web/controllers/setting_html/show.html.heex new file mode 100644 index 0000000..04ef18e --- /dev/null +++ b/lib/chiya_web/controllers/setting_html/show.html.heex @@ -0,0 +1,28 @@ +<.header> + Settings + <:subtitle>These are your site's settings. + <:actions> + <%= if @setting == nil do %> + <.link href={~p"/admin/settings/new"}> + <.button>Create settings + + <% else %> + <.link href={~p"/admin/settings/edit"}> + <.button>Edit settings + + <% end %> + + + +<%= if @setting !== nil do %> + +<.list> + <:item title="Title"><%= @setting.title %> + <:item title="Subtitle"><%= @setting.subtitle %> + <:item title="Theme"><%= @setting.theme %> + <:item title="User agent"><%= @setting.user_agent %> + <:item title="Custom css"><%= @setting.custom_css %> + <:item title="Custom html"><%= @setting.custom_html %> + + +<% end %> diff --git a/lib/chiya_web/live/user_settings_live.ex b/lib/chiya_web/live/user_settings_live.ex index fe2c0c0..a34b8de 100644 --- a/lib/chiya_web/live/user_settings_live.ex +++ b/lib/chiya_web/live/user_settings_live.ex @@ -23,7 +23,7 @@ defmodule ChiyaWeb.UserSettingsLive do - <.line /> + <.line /> <.header>Change Email @@ -48,7 +48,7 @@ defmodule ChiyaWeb.UserSettingsLive do - <.line /> + <.line /> <.header>Change Password @@ -140,7 +140,7 @@ defmodule ChiyaWeb.UserSettingsLive do IO.inspect(path) {:ok, _user} = Accounts.update_user_image(user, %{user_image: path}) IO.inspect("SUCCESS") - {:ok, path} + {:ok, path} end) {:noreply, update(socket, :uploaded_files, &(&1 ++ uploaded_files))} diff --git a/lib/chiya_web/router.ex b/lib/chiya_web/router.ex index 827d319..a9cebf0 100644 --- a/lib/chiya_web/router.ex +++ b/lib/chiya_web/router.ex @@ -52,6 +52,7 @@ defmodule ChiyaWeb.Router do resources "/channels", ChannelController resources "/notes", NoteController + resources "/settings", SettingController, singleton: true end ## Authentication routes diff --git a/priv/repo/migrations/20230307204825_create_settings.exs b/priv/repo/migrations/20230307204825_create_settings.exs new file mode 100644 index 0000000..3522cc1 --- /dev/null +++ b/priv/repo/migrations/20230307204825_create_settings.exs @@ -0,0 +1,16 @@ +defmodule Chiya.Repo.Migrations.CreateSettings do + use Ecto.Migration + + def change do + create table(:settings) do + add :title, :string + add :subtitle, :string + add :theme, :string + add :user_agent, :string + add :custom_css, :text + add :custom_html, :text + + timestamps() + end + end +end diff --git a/test/chiya/site_test.exs b/test/chiya/site_test.exs new file mode 100644 index 0000000..5a9f379 --- /dev/null +++ b/test/chiya/site_test.exs @@ -0,0 +1,58 @@ +defmodule Chiya.SiteTest do + use Chiya.DataCase + + alias Chiya.Site + + describe "settings" do + alias Chiya.Site.Setting + + import Chiya.SiteFixtures + + @invalid_attrs %{custom_css: nil, custom_html: nil, subtitle: nil, theme: nil, title: nil, user_agent: nil} + + test "get_setting!/1 returns the setting with given id" do + setting = setting_fixture() + assert Site.get_settings() == setting + end + + test "create_setting/1 with valid data creates a setting" do + valid_attrs = %{custom_css: "some custom_css", custom_html: "some custom_html", subtitle: "some subtitle", theme: :default, title: "some title", user_agent: "some user_agent"} + + assert {:ok, %Setting{} = setting} = Site.create_setting(valid_attrs) + assert setting.custom_css == "some custom_css" + assert setting.custom_html == "some custom_html" + assert setting.subtitle == "some subtitle" + assert setting.theme == :default + assert setting.title == "some title" + assert setting.user_agent == "some user_agent" + end + + test "create_setting/1 with invalid data returns error changeset" do + assert {:error, %Ecto.Changeset{}} = Site.create_setting(@invalid_attrs) + end + + test "update_setting/2 with valid data updates the setting" do + setting = setting_fixture() + update_attrs = %{custom_css: "some updated custom_css", custom_html: "some updated custom_html", subtitle: "some updated subtitle", theme: :default, title: "some updated title", user_agent: "some updated user_agent"} + + assert {:ok, %Setting{} = setting} = Site.update_setting(setting, update_attrs) + assert setting.custom_css == "some updated custom_css" + assert setting.custom_html == "some updated custom_html" + assert setting.subtitle == "some updated subtitle" + assert setting.theme == :default + assert setting.title == "some updated title" + assert setting.user_agent == "some updated user_agent" + end + + test "update_setting/2 with invalid data returns error changeset" do + setting = setting_fixture() + assert {:error, %Ecto.Changeset{}} = Site.update_setting(setting, @invalid_attrs) + assert setting == Site.get_settings() + end + + test "change_setting/1 returns a setting changeset" do + setting = setting_fixture() + assert %Ecto.Changeset{} = Site.change_setting(setting) + end + end +end diff --git a/test/chiya_web/controllers/setting_controller_test.exs b/test/chiya_web/controllers/setting_controller_test.exs new file mode 100644 index 0000000..6e2b3e2 --- /dev/null +++ b/test/chiya_web/controllers/setting_controller_test.exs @@ -0,0 +1,61 @@ +defmodule ChiyaWeb.SettingControllerTest do + use ChiyaWeb.ConnCase + + import Chiya.SiteFixtures + + @create_attrs %{custom_css: "some custom_css", custom_html: "some custom_html", subtitle: "some subtitle", theme: :default, title: "some title", user_agent: "some user_agent"} + @update_attrs %{custom_css: "some updated custom_css", custom_html: "some updated custom_html", subtitle: "some updated subtitle", theme: :default, title: "some updated title", user_agent: "some updated user_agent"} + @invalid_attrs %{custom_css: nil, custom_html: nil, subtitle: nil, theme: nil, title: nil, user_agent: nil} + + setup [:register_and_log_in_user] + + describe "new setting" do + test "renders form", %{conn: conn} do + conn = get(conn, ~p"/admin/settings/new") + assert html_response(conn, 200) =~ "New Setting" + end + end + + describe "create setting" do + test "redirects to show when data is valid", %{conn: conn} do + conn = post(conn, ~p"/admin/settings", setting: @create_attrs) + assert redirected_to(conn) == ~p"/admin/settings" + end + + test "renders errors when data is invalid", %{conn: conn} do + conn = post(conn, ~p"/admin/settings", setting: @invalid_attrs) + assert html_response(conn, 200) =~ "New Setting" + end + end + + describe "edit setting" do + setup [:create_setting] + + test "renders form for editing chosen setting", %{conn: conn} do + conn = get(conn, ~p"/admin/settings/edit") + assert html_response(conn, 200) =~ "Edit Setting" + end + end + + describe "update setting" do + setup [:create_setting] + + test "redirects when data is valid", %{conn: conn} do + conn = put(conn, ~p"/admin/settings", setting: @update_attrs) + assert redirected_to(conn) == ~p"/admin/settings" + + conn = get(conn, ~p"/admin/settings") + assert html_response(conn, 200) =~ "some updated custom_css" + end + + test "renders errors when data is invalid", %{conn: conn} do + conn = put(conn, ~p"/admin/settings", setting: @invalid_attrs) + assert html_response(conn, 200) =~ "Edit Setting" + end + end + + defp create_setting(_) do + setting = setting_fixture() + %{setting: setting} + end +end diff --git a/test/chiya_web/controllers/user_session_controller_test.exs b/test/chiya_web/controllers/user_session_controller_test.exs index a9a2cc6..f8c1017 100644 --- a/test/chiya_web/controllers/user_session_controller_test.exs +++ b/test/chiya_web/controllers/user_session_controller_test.exs @@ -21,7 +21,7 @@ defmodule ChiyaWeb.UserSessionControllerTest do conn = get(conn, ~p"/") response = html_response(conn, 200) assert response =~ user.email - assert response =~ ~p"/user/settings" + assert response =~ ~p"/user" assert response =~ ~p"/user/log_out" end diff --git a/test/support/fixtures/site_fixtures.ex b/test/support/fixtures/site_fixtures.ex new file mode 100644 index 0000000..4dc6e64 --- /dev/null +++ b/test/support/fixtures/site_fixtures.ex @@ -0,0 +1,25 @@ +defmodule Chiya.SiteFixtures do + @moduledoc """ + This module defines test helpers for creating + entities via the `Chiya.Site` context. + """ + + @doc """ + Generate a setting. + """ + def setting_fixture(attrs \\ %{}) do + {:ok, setting} = + attrs + |> Enum.into(%{ + custom_css: "some custom_css", + custom_html: "some custom_html", + subtitle: "some subtitle", + theme: :default, + title: "some title", + user_agent: "some user_agent" + }) + |> Chiya.Site.create_setting() + + setting + end +end