<%= for {social, icon, url_base, social_value} <- assigns.socials_with_values do %>
<%= if social_value do %>

icon} class="h-5 w-5" alt={Atom.to_string(social)} />
<.link class="capitalize text-blue-500" target="_blank" href={url_base <> social_value}>
- {Atom.to_string(social)}
+ {social_value}
<% end %>
diff --git a/lib/atomic_web/live/profile_live/show.ex b/lib/atomic_web/live/profile_live/show.ex
index 3ea935d48..aedd7fe46 100644
--- a/lib/atomic_web/live/profile_live/show.ex
+++ b/lib/atomic_web/live/profile_live/show.ex
@@ -1,9 +1,10 @@
defmodule AtomicWeb.ProfileLive.Show do
use AtomicWeb, :live_view
- import AtomicWeb.Components.{Button, Avatar, Gradient, Socials}
+ import AtomicWeb.Components.{Button, Tabs, Avatar, Gradient, Socials}
import AtomicWeb.Components.ImageUploader
import AtomicWeb.LiveHelpers
+ alias AtomicWeb.HomeLive.Components.FollowSuggestions.Suggestion
alias Atomic.Accounts
alias Atomic.Organizations
@@ -27,7 +28,7 @@ defmodule AtomicWeb.ProfileLive.Show do
end
@impl true
- def handle_params(%{"slug" => user_slug}, _, socket) do
+ def handle_params(%{"slug" => user_slug} = params, _, socket) do
user = Accounts.get_user_by_slug(user_slug)
is_current_user =
@@ -35,6 +36,8 @@ defmodule AtomicWeb.ProfileLive.Show do
organizations = Organizations.list_user_organizations(user.id)
+ memberships = Organizations.list_memberships(%{"user_id" => user.id}, [:organization])
+
{:noreply,
socket
|> assign(:page_title, user.name)
@@ -42,6 +45,70 @@ defmodule AtomicWeb.ProfileLive.Show do
|> assign(:current_page, :profile)
|> assign(:user, user)
|> assign(:organizations, organizations)
- |> assign(:is_current_user, is_current_user)}
+ |> assign(:memberships, memberships)
+ |> assign(:is_current_user, is_current_user)
+ |> assign(:current_tab, current_tab(socket, params))}
+ end
+
+ @impl true
+ def handle_event("unfollow", %{"organization_id" => organization_id}, socket) do
+ membership =
+ Organizations.get_membership_by_user_id_and_organization_id!(
+ socket.assigns.current_user.id,
+ organization_id
+ )
+
+ organization = Organizations.get_organization!(organization_id)
+
+ case Organizations.delete_membership(membership) do
+ {:ok, _organization} ->
+ # Reloads memberships list after unfollowing a new one
+ memberships =
+ Organizations.list_memberships(%{"user_id" => socket.assigns.user.id}, [:organization])
+
+ {:noreply,
+ socket
+ |> assign(:memberships, memberships || [])
+ |> put_flash(:success, "Unfollowed " <> organization.name)}
+
+ {:error, _changeset} ->
+ {:noreply,
+ socket
+ |> put_flash(:error, "Failed to unfollow " <> organization.name)}
+ end
+ end
+
+ @impl true
+ def handle_event("follow", %{"organization_id" => organization_id}, socket) do
+ attrs = %{
+ role: :follower,
+ user_id: socket.assigns.current_user.id,
+ created_by_id: socket.assigns.current_user.id,
+ organization_id: organization_id
+ }
+
+ organization = Organizations.get_organization!(organization_id)
+
+ case Organizations.create_membership(attrs) do
+ {:ok, _organization} ->
+ # Reloads memberships list after following a new one
+ memberships =
+ Organizations.list_memberships(%{"user_id" => socket.assigns.user.id}, [:organization])
+
+ {:noreply,
+ socket
+ |> assign(:memberships, memberships || [])
+ |> put_flash(:success, "Started following " <> organization.name)
+ |> push_patch(to: ~p"/profile/#{socket.assigns.user.slug}")}
+
+ {:error, %Ecto.Changeset{} = changeset} ->
+ {:noreply, assign(socket, :changeset, changeset)}
+ end
+ end
+
+ defp current_tab(_socket, params) when is_map_key(params, "tab") do
+ params["tab"]
end
+
+ defp current_tab(_socket, _params), do: "following"
end
diff --git a/lib/atomic_web/live/profile_live/show.html.heex b/lib/atomic_web/live/profile_live/show.html.heex
index a41eef204..47eaef948 100644
--- a/lib/atomic_web/live/profile_live/show.html.heex
+++ b/lib/atomic_web/live/profile_live/show.html.heex
@@ -1,5 +1,7 @@
-
+
+
+
<%= if @user.banner do %>
<.image_uploader editable={false} id="banner-picture" class="h-64 w-full" image_class="h-[290px] w-full object-cover" upload={@uploads.banner} icon="hero-photo" memory_unit="MB" image={Uploaders.Banner.url({@user.banner, @user}, :original, signed: true)} />
@@ -7,76 +9,142 @@
<.gradient class="h-64 w-full bg-center object-cover" seed={@user.id} />
<% end %>
-
-
-
-
- <%= if @user.profile_picture do %>
- <.image_uploader editable={false} id="profile-picture" class="aspect-square w-36 border-4 border-white" rounded upload={@uploads.profile_picture} icon="hero-user" memory_unit="GB" image={Uploaders.ProfilePicture.url({@user.profile_picture, @user}, :original, signed: true)}>
- <:placeholder>
- <.avatar size={:xl} name={@user.name} type={:user} />
-
-
- <% else %>
- <.avatar size={:xl} name={@user.name} type={:user} />
- <% end %>
-
+
+
+
+
+
+ <%= if @user.profile_picture do %>
+ <.image_uploader editable={false} id="profile-picture" class="aspect-square w-36 border-4 border-white" rounded upload={@uploads.profile_picture} icon="hero-user" memory_unit="GB" image={Uploaders.ProfilePicture.url({@user.profile_picture, @user}, :original, signed: true)}>
+ <:placeholder>
+ <.avatar size={:xxl} name={@user.name} type={:user} />
+
+
+ <% else %>
+ <.avatar size={:xxl} name={@user.name} type={:user} />
+ <% end %>
-
-
- {@user.name}
-
-
- <%= if length(@organizations) > 0 do %>
-
- <%= for organization <- @organizations do %>
-
- {organization.name} - {Atomic.Organizations.get_role(@user.id, organization.id)}
-
- <% end %>
-
- <% else %>
-
{gettext("No organizations found.")}
- <% end %>
-
- <%= if @user.socials do %>
-
- <.socials entity={@user} />
+
+
+
+
+
+
+
+
+
+ {@user.name}
+
+
+
+
+ <%= if length(@organizations) > 0 do %>
+
+ <%= for organization <- @organizations do %>
+
+ {organization.name} - {Atomic.Organizations.get_role(@user.id, organization.id)}
+
+ <% end %>
+ <% else %>
+
{gettext("No organizations found.")}
<% end %>
-
- <%= if @user.email do %>
-
- <% end %>
- <%= if @user.phone_number do %>
-
- <% end %>
-
+
+
+ <%= if @user.socials do %>
+
+ <.socials entity={@user} />
+
+ <% end %>
+
+
+
+
+ <%= if @is_current_user do %>
+ <.button patch={~p"/profile/#{@user}/edit"} icon="hero-pencil-square" size={:md} full_width={true}>
+ {gettext("Edit Profile")}
+
+ <% end %>
-
- <%= if @is_current_user do %>
-
- <.button patch={~p"/profile/#{@user}/edit"}>
- {gettext("Edit")}
-
+
+
+
+
+
+
+ <.tabs class="px-4 sm:px-6 lg:px-8">
+ <.link patch="?tab=following" replace={false}>
+ <.tab active={@current_tab == "following"}>
+ {gettext("Following")}
+
+
+ <.link patch="?tab=activity" replace={false}>
+ <.tab active={@current_tab == "activity"}>
+ {gettext("Activity")}
+
+
+ <.link patch="?tab=about" replace={false}>
+ <.tab active={@current_tab == "about"}>
+ {gettext("About")}
+
+
+
- <% end %>
+
+
+ <%= case @current_tab do %>
+ <% "following" -> %>
+
+
+
{gettext("Following Organizations:")}
+
+
+
+
+ <% "activity" -> %>
+
+ <% "about" -> %>
+
+ <% end %>
diff --git a/lib/atomic_web/templates/layout/live.html.heex b/lib/atomic_web/templates/layout/live.html.heex
index 461ff37d1..2a5dac7cc 100644
--- a/lib/atomic_web/templates/layout/live.html.heex
+++ b/lib/atomic_web/templates/layout/live.html.heex
@@ -12,7 +12,7 @@
{render("_live_navbar.html", assigns)}
-