From 2224b08c15e72d68e3ee125ebb2007d9e0794172 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rio=20Rodrigues?= Date: Sun, 6 Aug 2023 01:55:06 +0100 Subject: [PATCH] Add news --- lib/atomic/news.ex | 116 ++++++++++++++++++ lib/atomic/news/new.ex | 25 ++++ lib/atomic/organizations/organization.ex | 7 ++ lib/atomic_web/live/home_live/index.ex | 4 + lib/atomic_web/live/home_live/index.html.heex | 2 +- .../2022000000000_create_organizations.exs | 1 - .../migrations/20230830011755_add_news.exs | 17 +++ priv/repo/seeds.exs | 3 +- priv/repo/seeds/news.exs | 27 ++++ test/support/factories/news_factory.ex | 18 +++ 10 files changed, 217 insertions(+), 3 deletions(-) create mode 100644 lib/atomic/news.ex create mode 100644 lib/atomic/news/new.ex create mode 100644 priv/repo/migrations/20230830011755_add_news.exs create mode 100644 priv/repo/seeds/news.exs create mode 100644 test/support/factories/news_factory.ex diff --git a/lib/atomic/news.ex b/lib/atomic/news.ex new file mode 100644 index 000000000..e66422624 --- /dev/null +++ b/lib/atomic/news.ex @@ -0,0 +1,116 @@ +defmodule Atomic.News do + @moduledoc """ + The news context. + """ + + alias Atomic.News.New + alias Atomic.Repo + + @doc """ + Returns the list of news. + + ## Examples + + iex> list_news() + [%New{}, ...] + + """ + def list_news do + Repo.all(New) + end + + @doc """ + Returns the list of news belonging to an organization. + + ## Examples + + iex> list_news_by_organization_id(99d7c9e5-4212-4f59-a097-28aaa33c2621) + [%New{}, ...] + + """ + def list_news_by_organization_id(id) do + Repo.all(New) + |> Enum.filter(fn new -> new.organization_id == id end) + end + + @doc """ + Gets a single new. + + Raises `Ecto.NoResultsError` if the new does not exist. + + ## Examples + + iex> get_new!(123) + %New{} + + iex> get_new!(456) + ** (Ecto.NoResultsError) + + """ + def get_new!(id), do: Repo.get!(New, id) + + @doc """ + Creates a new. + + ## Examples + + iex> create_new(%{field: value}) + {:ok, %New{}} + + iex> create_new(%{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def create_new(attrs \\ %{}, _after_save \\ &{:ok, &1}) do + %New{} + |> New.changeset(attrs) + |> Repo.insert() + end + + @doc """ + Updates a new. + + ## Examples + + iex> update_new(new, %{field: new_value}) + {:ok, %New{}} + + iex> update_new(new, %{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def update_new(%New{} = new, attrs, _after_save \\ &{:ok, &1}) do + new + |> New.changeset(attrs) + |> Repo.update() + end + + @doc """ + Deletes a new. + + ## Examples + + iex> delete_new(New) + {:ok, %New{}} + + iex> delete_new(New) + {:error, %Ecto.Changeset{}} + + """ + def delete_new(%New{} = new) do + Repo.delete(new) + end + + @doc """ + Returns an `%Ecto.Changeset{}` for tracking new changes. + + ## Examples + + iex> change_new(new) + %Ecto.Changeset{data: %New{}} + + """ + def change_new(%New{} = new, attrs \\ %{}) do + New.changeset(new, attrs) + end +end diff --git a/lib/atomic/news/new.ex b/lib/atomic/news/new.ex new file mode 100644 index 000000000..668fe48a1 --- /dev/null +++ b/lib/atomic/news/new.ex @@ -0,0 +1,25 @@ +defmodule Atomic.News.New do + @moduledoc """ + The person who speaks and provides the activity + """ + use Atomic.Schema + alias Atomic.Organizations.Organization + + @required_fields ~w(title description organization_id)a + + schema "news" do + field :title, :string + field :description, :string + + belongs_to :organization, Organization, on_replace: :delete_if_exists + + timestamps() + end + + @doc false + def changeset(new, attrs) do + new + |> cast(attrs, @required_fields) + |> validate_required(@required_fields) + end +end diff --git a/lib/atomic/organizations/organization.ex b/lib/atomic/organizations/organization.ex index ef5064ef0..9e59564d9 100644 --- a/lib/atomic/organizations/organization.ex +++ b/lib/atomic/organizations/organization.ex @@ -3,6 +3,7 @@ defmodule Atomic.Organizations.Organization do use Atomic.Schema alias Atomic.Accounts.User alias Atomic.Activities.Location + alias Atomic.News.New alias Atomic.Organizations.Card alias Atomic.Organizations.Department alias Atomic.Organizations.Membership @@ -34,6 +35,12 @@ defmodule Atomic.Organizations.Organization do embeds_one :location, Location, on_replace: :delete embeds_one :card, Card, on_replace: :delete + has_many :news, New, + on_replace: :delete_if_exists, + on_delete: :delete_all, + foreign_key: :organization_id, + preload_order: [asc: :title] + timestamps() end diff --git a/lib/atomic_web/live/home_live/index.ex b/lib/atomic_web/live/home_live/index.ex index 80e4a300f..68c1ef4fb 100644 --- a/lib/atomic_web/live/home_live/index.ex +++ b/lib/atomic_web/live/home_live/index.ex @@ -3,6 +3,7 @@ defmodule AtomicWeb.HomeLive.Index do use AtomicWeb, :live_view alias Atomic.Activities + alias Atomic.News alias Atomic.Partnerships alias Atomic.Uploaders.Card @@ -23,6 +24,8 @@ defmodule AtomicWeb.HomeLive.Index do activities = Activities.list_activities_by_organization_id(socket.assigns.current_organization.id, []) + news = News.list_news_by_organization_id(socket.assigns.current_organization.id) + mode = params["mode"] || "month" entries = [ @@ -37,6 +40,7 @@ defmodule AtomicWeb.HomeLive.Index do |> assign(:page_title, "Home") |> assign(:breadcrumb_entries, entries) |> assign(:current_page, :home) + |> assign(:news, news) |> assign(:partners, partners) |> assign(:activities, activities) |> assign(:time_zone, socket.assigns.time_zone) diff --git a/lib/atomic_web/live/home_live/index.html.heex b/lib/atomic_web/live/home_live/index.html.heex index 0d42d4a5a..2c7574d99 100644 --- a/lib/atomic_web/live/home_live/index.html.heex +++ b/lib/atomic_web/live/home_live/index.html.heex @@ -21,7 +21,7 @@ <%= live_patch("See all", to: Routes.partner_index_path(@socket, :index, @current_organization), class: "text-sm font-semibold text-gray-300 ml-4") %>