<%= @title %>
diff --git a/lib/atomic_web/config.ex b/lib/atomic_web/config.ex
index 03f60860..ef36a0ed 100644
--- a/lib/atomic_web/config.ex
+++ b/lib/atomic_web/config.ex
@@ -43,6 +43,13 @@ defmodule AtomicWeb.Config do
url: ~p"/organizations/#{current_organization}/departments",
tabs: []
},
+ %{
+ key: :announcements,
+ title: "Announcements",
+ icon: "hero-newspaper",
+ url: ~p"/organizations/#{current_organization}/announcements",
+ tabs: []
+ },
%{
key: :partners,
title: "Partners",
@@ -83,13 +90,6 @@ defmodule AtomicWeb.Config do
url: ~p"/activities",
tabs: []
},
- %{
- key: :announcements,
- title: "Announcements",
- icon: "hero-newspaper",
- url: ~p"/announcements",
- tabs: []
- },
%{
key: :organizations,
title: "Organizations",
diff --git a/lib/atomic_web/live/announcement_live/components/announcement_card.ex b/lib/atomic_web/live/announcement_live/components/announcement_card.ex
new file mode 100644
index 00000000..cabb52d1
--- /dev/null
+++ b/lib/atomic_web/live/announcement_live/components/announcement_card.ex
@@ -0,0 +1,41 @@
+defmodule AtomicWeb.AnnouncementLive.Components.AnnouncementCard do
+ @moduledoc false
+
+ import AtomicWeb.Components.Avatar
+
+ use AtomicWeb, :component
+
+ def announcement_card(assigns) do
+ ~H"""
+
+ <.link navigate={~p"/organizations/#{@organization}/announcements/#{@announcement}"} class="block">
+
+
+ <.avatar name={@announcement.organization.name} color={:light_zinc} class="!h-10 !w-10" size={:xs} type={:organization} src={Uploaders.Logo.url({@announcement.organization.logo, @announcement.organization}, :original)} />
+
+
+ <%= @announcement.organization.name %>
+
+ Published on
+
+
+
+
+
+
+ <%= @announcement.title %>
+
+
+ <%= maybe_slice_string(@announcement.description, 300) %>
+
+
+ <%= if @announcement.image do %>
+
+
+
+ <% end %>
+
+
+ """
+ end
+end
diff --git a/lib/atomic_web/live/announcement_live/edit.ex b/lib/atomic_web/live/announcement_live/edit.ex
index aee94bed..fe634a5c 100644
--- a/lib/atomic_web/live/announcement_live/edit.ex
+++ b/lib/atomic_web/live/announcement_live/edit.ex
@@ -16,7 +16,9 @@ defmodule AtomicWeb.AnnouncementLive.Edit do
{:noreply,
socket
|> put_flash(:info, gettext("Announcement deleted successfully"))
- |> push_navigate(to: ~p"/announcements")}
+ |> push_navigate(
+ to: ~p"/organizations/#{socket.assigns.current_organization.id}/announcements"
+ )}
end
@impl true
diff --git a/lib/atomic_web/live/announcement_live/edit.html.heex b/lib/atomic_web/live/announcement_live/edit.html.heex
index c3db0c4f..6b36d4a3 100644
--- a/lib/atomic_web/live/announcement_live/edit.html.heex
+++ b/lib/atomic_web/live/announcement_live/edit.html.heex
@@ -5,6 +5,6 @@
- <.live_component module={AtomicWeb.AnnouncementLive.FormComponent} id={@announcement.id} organization={@current_organization} title={@page_title} action={@live_action} announcement={@announcement} return_to={~p"/announcements/#{@announcement}"} />
+ <.live_component module={AtomicWeb.AnnouncementLive.FormComponent} id={@announcement.id} organization={@current_organization} title={@page_title} action={@live_action} announcement={@announcement} return_to={~p"/organizations/#{@current_organization}/announcements"} />
diff --git a/lib/atomic_web/live/announcement_live/form_component.ex b/lib/atomic_web/live/announcement_live/form_component.ex
index dc264e02..feb604a8 100644
--- a/lib/atomic_web/live/announcement_live/form_component.ex
+++ b/lib/atomic_web/live/announcement_live/form_component.ex
@@ -2,6 +2,7 @@ defmodule AtomicWeb.AnnouncementLive.FormComponent do
use AtomicWeb, :live_component
alias Atomic.Organizations
+ alias AtomicWeb.Components.ImageUploader
import AtomicWeb.Components.Forms
@@ -17,7 +18,8 @@ defmodule AtomicWeb.AnnouncementLive.FormComponent do
{:ok,
socket
|> assign(assigns)
- |> assign(:changeset, changeset)}
+ |> assign(:changeset, changeset)
+ |> allow_upload(:image, accept: Uploaders.Post.extension_whitelist(), max_entries: 1)}
end
@impl true
@@ -35,10 +37,16 @@ defmodule AtomicWeb.AnnouncementLive.FormComponent do
save_announcement(socket, socket.assigns.action, announcement_params)
end
+ @impl true
+ def handle_event("cancel-image", %{"ref" => ref}, socket) do
+ {:noreply, cancel_upload(socket, :image, ref)}
+ end
+
defp save_announcement(socket, :edit, announcement_params) do
case Organizations.update_announcement(
socket.assigns.announcement,
- announcement_params
+ announcement_params,
+ &consume_image_data(socket, &1)
) do
{:ok, _announcement} ->
{:noreply,
@@ -55,7 +63,10 @@ defmodule AtomicWeb.AnnouncementLive.FormComponent do
announcement_params =
Map.put(announcement_params, "organization_id", socket.assigns.organization.id)
- case Organizations.create_announcement_with_post(announcement_params) do
+ case Organizations.create_announcement_with_post(
+ announcement_params,
+ &consume_image_data(socket, &1)
+ ) do
{:ok, _announcement} ->
{:noreply,
socket
@@ -66,4 +77,23 @@ defmodule AtomicWeb.AnnouncementLive.FormComponent do
{:noreply, assign(socket, :changeset, changeset)}
end
end
+
+ defp consume_image_data(socket, announcement) do
+ consume_uploaded_entries(socket, :image, fn %{path: path}, entry ->
+ Organizations.update_announcement_image(announcement, %{
+ "image" => %Plug.Upload{
+ content_type: entry.client_type,
+ filename: entry.client_name,
+ path: path
+ }
+ })
+ end)
+ |> case do
+ [{:ok, announcement}] ->
+ {:ok, announcement}
+
+ _errors ->
+ {:ok, announcement}
+ end
+ end
end
diff --git a/lib/atomic_web/live/announcement_live/form_component.html.heex b/lib/atomic_web/live/announcement_live/form_component.html.heex
index 8f06c954..bdd53a77 100644
--- a/lib/atomic_web/live/announcement_live/form_component.html.heex
+++ b/lib/atomic_web/live/announcement_live/form_component.html.heex
@@ -1,11 +1,20 @@
-
- <.form :let={f} for={@changeset} id="announcement-form" phx-target={@myself} phx-change="validate" phx-submit="save">
- <.field field={f[:title]} help_text={gettext("The title of the announcement")} type="text" placeholder="Title" required />
+
+ <.form :let={f} for={@changeset} id="announcement-form" phx-target={@myself} phx-change="validate" phx-submit="save" class="space-y-6">
+
+
+
+ <.field field={f[:title]} type="text" placeholder="Title" required class="w-full" />
- <.field field={f[:description]} help_text={gettext("Announcement description")} type="text" placeholder="Description" required />
+ <.field field={f[:description]} type="textarea" placeholder="Description" required class="w-full overflow-auto resize-none h-44 xl:h-64" />
+
+
+ <.live_component module={ImageUploader} id="uploader" uploads={@uploads} target={@myself} class="object-cover" />
-
- <.button size={:md} color={:white} icon="hero-cube" type="submit"><%= gettext("Save Changes") %>
+
+ <.button size={:md} color={:white} icon="hero-cube" type="submit"><%= gettext("Save Changes") %>
+
+
+
diff --git a/lib/atomic_web/live/announcement_live/index.ex b/lib/atomic_web/live/announcement_live/index.ex
index 2c26e45b..b30dd934 100644
--- a/lib/atomic_web/live/announcement_live/index.ex
+++ b/lib/atomic_web/live/announcement_live/index.ex
@@ -1,7 +1,8 @@
defmodule AtomicWeb.AnnouncementLive.Index do
use AtomicWeb, :live_view
- import AtomicWeb.Components.{Button, Empty, Pagination, Tabs}
+ import AtomicWeb.Components.{Button, Empty, Pagination}
+ import AtomicWeb.AnnouncementLive.Components.AnnouncementCard
alias Atomic.Accounts
alias Atomic.Organizations
@@ -12,44 +13,24 @@ defmodule AtomicWeb.AnnouncementLive.Index do
end
@impl true
- def handle_params(params, _, socket) do
+ def handle_params(%{"organization_id" => organization_id} = params, _, socket) do
+ organization = Organizations.get_organization!(organization_id)
+
{:noreply,
socket
|> assign(:page_title, gettext("Announcements"))
|> assign(:current_page, :announcements)
- |> assign(:current_tab, current_tab(socket, params))
+ |> assign(:organization, organization)
|> assign(:params, params)
|> assign(:has_permissions?, has_permissions?(socket))
- |> assign(list_announcements(socket, params))
+ |> assign(list_announcements_by_organization(socket, params, organization_id))
|> then(fn complete_socket ->
assign(complete_socket, :empty?, Enum.empty?(complete_socket.assigns.announcements))
end)}
end
- defp list_announcements(socket, params) do
- params = Map.put(params, "page_size", 6)
-
- case current_tab(socket, params) do
- "all" -> list_all_announcements(socket, params)
- "following" -> list_following_announcements(socket, params)
- end
- end
-
- defp list_all_announcements(_socket, params) do
- case Organizations.list_announcements(params, preloads: [:organization]) do
- {:ok, {announcements, meta}} ->
- %{announcements: announcements, meta: meta}
-
- {:error, flop} ->
- %{announcements: [], meta: flop}
- end
- end
-
- defp list_following_announcements(socket, params) do
- organizations =
- Organizations.list_organizations_followed_by_user(socket.assigns.current_user.id)
-
- case Organizations.list_organizations_announcements(organizations, params,
+ defp list_announcements_by_organization(_socket, params, organization_id) do
+ case Organizations.list_announcements_by_organization_id(organization_id, params,
preloads: [:organization]
) do
{:ok, {announcements, meta}} ->
@@ -60,9 +41,6 @@ defmodule AtomicWeb.AnnouncementLive.Index do
end
end
- defp current_tab(_socket, params) when is_map_key(params, "tab"), do: params["tab"]
- defp current_tab(_socket, _params), do: "all"
-
defp has_permissions?(socket) when not socket.assigns.is_authenticated?, do: false
defp has_permissions?(socket) do
diff --git a/lib/atomic_web/live/announcement_live/index.html.heex b/lib/atomic_web/live/announcement_live/index.html.heex
index 623e7d4b..67596eaa 100644
--- a/lib/atomic_web/live/announcement_live/index.html.heex
+++ b/lib/atomic_web/live/announcement_live/index.html.heex
@@ -1,47 +1,22 @@
-<.page title="Announcements">
+<.page title="Announcements" bottom_border={true}>
<:actions>
<%= if not @empty? and @has_permissions? do %>
- <.button navigate={~p"/announcements/new"}>
- <%= gettext("New") %>
+ <.button navigate={~p"/organizations/#{@current_organization}/announcements/new"} icon="hero-plus">
+ <%= gettext("New Announcement") %>
<% end %>
-
- <.tabs class="max-w-5-xl mx-auto px-4 sm:px-6 lg:px-8">
- <.link patch="?tab=all" replace={false}>
- <.tab active={@current_tab == "all"}>
- <%= gettext("All") %>
-
-
-
- <.link patch="?tab=following" replace={false}>
- <.tab active={@current_tab == "following"}>
- <%= gettext("Following") %>
-
-
-
<%= if @empty? and @has_permissions? do %>
- <.empty_state url={~p"/announcements/new"} placeholder="announcement" />
+ <.empty_state url={~p"/organizations/#{@organization}/announcements/new"} placeholder="announcement" />
<% else %>
<%= for announcement <- @announcements do %>
-
- <.link navigate={~p"/announcements/#{announcement}"} class="block hover:bg-zinc-50">
-
-
-
- <%= announcement.title %>
-
-
-
- <%= announcement.description %>
-
-
-
+ <.announcement_card announcement={announcement} organization={@organization} />
<% end %>
diff --git a/lib/atomic_web/live/announcement_live/new.html.heex b/lib/atomic_web/live/announcement_live/new.html.heex
index bda286c4..a944ab48 100644
--- a/lib/atomic_web/live/announcement_live/new.html.heex
+++ b/lib/atomic_web/live/announcement_live/new.html.heex
@@ -1,5 +1,5 @@
<.page title={gettext("New Announcement")}>
- <.live_component module={AtomicWeb.AnnouncementLive.FormComponent} id={:new} organization={@current_organization} title={@page_title} action={@live_action} announcement={@announcement} return_to={~p"/announcements"} />
+ <.live_component module={AtomicWeb.AnnouncementLive.FormComponent} id={:new} organization={@current_organization} title={@page_title} action={@live_action} announcement={@announcement} return_to={~p"/organizations/#{@current_organization}/announcements"} />
diff --git a/lib/atomic_web/live/announcement_live/show.ex b/lib/atomic_web/live/announcement_live/show.ex
index 41c8b5c7..b741f240 100644
--- a/lib/atomic_web/live/announcement_live/show.ex
+++ b/lib/atomic_web/live/announcement_live/show.ex
@@ -1,6 +1,8 @@
defmodule AtomicWeb.AnnouncementLive.Show do
use AtomicWeb, :live_view
+ import AtomicWeb.Components.Avatar
+
alias Atomic.Accounts
alias Atomic.Organizations
@@ -18,7 +20,7 @@ defmodule AtomicWeb.AnnouncementLive.Show do
|> assign(:page_title, "#{announcement.title}")
|> assign(:current_page, :announcements)
|> assign(:announcement, announcement)
- |> assign(:has_permissions?, has_permissions?(socket))}
+ |> assign(:has_permissions?, has_permissions?(socket |> assign(:announcement, announcement)))}
end
defp has_permissions?(socket) when not socket.assigns.is_authenticated?, do: false
@@ -33,7 +35,7 @@ defmodule AtomicWeb.AnnouncementLive.Show do
Accounts.has_master_permissions?(socket.assigns.current_user.id) ||
Accounts.has_permissions_inside_organization?(
socket.assigns.current_user.id,
- socket.assigns.current_organization.id
+ socket.assigns.announcement.organization.id
)
end
end
diff --git a/lib/atomic_web/live/announcement_live/show.html.heex b/lib/atomic_web/live/announcement_live/show.html.heex
index 308ae58e..a54ffc66 100644
--- a/lib/atomic_web/live/announcement_live/show.html.heex
+++ b/lib/atomic_web/live/announcement_live/show.html.heex
@@ -1,22 +1,40 @@
-
-
-
-
-
+<.page title="Announcements" bottom_border={true}>
+ <:actions>
+ <%= if @has_permissions? do %>
+ <.button navigate={~p"/organizations/#{@announcement.organization}/announcements/#{@announcement}/edit"} icon="hero-pencil-solid"><%= gettext("Edit Announcement") %>
+ <% end %>
+
+
+
+
+
+ <.avatar name={@announcement.organization.name} color={:light_zinc} size={:md} type={:organization} src={Uploaders.Logo.url({@announcement.organization.logo, @announcement.organization}, :original)} />
+
+
+ <%= @announcement.organization.name %>
+
+ Published on
+
+
+
+
+
+
<%= @announcement.title %>
-
+
+
+
+ <%= Enum.map(String.split(@announcement.description, "\n"), fn phrase -> %>
+ <%= phrase %>
+ <% end) %>
+
+
-
- <%= @announcement.description %>
-
+ <%= if @announcement.image do %>
+
+
+
+ <% end %>
-
-
-<%= if @has_permissions? do %>
- <.link patch={~p"/organizations/#{@announcement.organization}/announcements/#{@announcement}/edit"} class="px-2 button">
-
-
-<% end %>
+
diff --git a/lib/atomic_web/router.ex b/lib/atomic_web/router.ex
index 9843a8c8..e7d91872 100644
--- a/lib/atomic_web/router.ex
+++ b/lib/atomic_web/router.ex
@@ -132,6 +132,12 @@ defmodule AtomicWeb.Router do
live "/", PartnerLive.Index, :index
live "/:id", PartnerLive.Show, :show
end
+
+ scope "/announcements" do
+ pipe_through :confirm_announcement_association
+ live "/", AnnouncementLive.Index, :index
+ live "/:id", AnnouncementLive.Show, :show
+ end
end
# Only masters can create organizations
<%= @announcement.organization.name %>
++ Published on + +
++ <%= @announcement.title %> +
++ <%= maybe_slice_string(@announcement.description, 300) %> +
+-
<%= for announcement <- @announcements do %>
-
- <.link navigate={~p"/announcements/#{announcement}"} class="block hover:bg-zinc-50">
- -- + <.announcement_card announcement={announcement} organization={@organization} />--
- <%= announcement.title %> -
-- <%= announcement.description %> -
-
<% end %>
+<.page title="Announcements" bottom_border={true}>
+ <:actions>
+ <%= if @has_permissions? do %>
+ <.button navigate={~p"/organizations/#{@announcement.organization}/announcements/#{@announcement}/edit"} icon="hero-pencil-solid"><%= gettext("Edit Announcement") %>
+ <% end %>
+
+
+
+
+
+ <.avatar name={@announcement.organization.name} color={:light_zinc} size={:md} type={:organization} src={Uploaders.Logo.url({@announcement.organization.logo, @announcement.organization}, :original)} />
+
+
+ <%= @announcement.organization.name %>
+
+ Published on
+
+
+
+
+
+
<%= @announcement.title %>
-
+
+
+
+ <%= Enum.map(String.split(@announcement.description, "\n"), fn phrase -> %>
+ <%= phrase %>
+ <% end) %>
+
+
-
- <%= @announcement.description %>
-
+ <%= if @announcement.image do %>
+
+
+
+ <% end %>
-
<%= @announcement.organization.name %>
++ Published on + +
+<%= @announcement.title %> - +
++ + <%= Enum.map(String.split(@announcement.description, "\n"), fn phrase -> %> + <%= phrase %> + <% end) %> + +
- <%= @announcement.description %> -
+ <%= if @announcement.image do %> +