From 99b28b416274010a05597ff5b2306081b98093ac Mon Sep 17 00:00:00 2001 From: Afonso Martins Date: Mon, 23 Sep 2024 19:38:51 +0100 Subject: [PATCH 01/13] feat: initial profile page --- lib/atomic/accounts/user.ex | 5 +- .../live/profile_live/form_component.ex | 47 +++++++++- .../profile_live/form_component.html.heex | 86 ------------------- lib/atomic_web/live/profile_live/show.ex | 3 +- .../live/profile_live/show.html.heex | 81 ++++++++++++----- 5 files changed, 108 insertions(+), 114 deletions(-) delete mode 100644 lib/atomic_web/live/profile_live/form_component.html.heex diff --git a/lib/atomic/accounts/user.ex b/lib/atomic/accounts/user.ex index f4dcba537..19de202aa 100644 --- a/lib/atomic/accounts/user.ex +++ b/lib/atomic/accounts/user.ex @@ -12,6 +12,7 @@ defmodule Atomic.Accounts.User do alias Atomic.Accounts.Course alias Atomic.Activities.Enrollment alias Atomic.Organizations.{Collaborator, Membership, Organization} + alias Atomic.Socials @required_fields ~w(email password)a @optional_fields ~w(name slug role confirmed_at phone_number course_id current_organization_id)a @@ -39,6 +40,8 @@ defmodule Atomic.Accounts.User do has_many :enrollments, Enrollment has_many :collaborators, Collaborator + embeds_one :socials, Socials, on_replace: :update + many_to_many :organizations, Organization, join_through: Membership timestamps() @@ -70,7 +73,6 @@ defmodule Atomic.Accounts.User do def picture_changeset(user, attrs) do user - |> cast(attrs, @required_fields ++ @optional_fields) |> cast_attachments(attrs, [:profile_picture]) end @@ -83,6 +85,7 @@ defmodule Atomic.Accounts.User do |> validate_email() |> validate_slug() |> validate_phone_number() + |> cast_embed(:socials, with: &Socials.changeset/2) end defp validate_email(changeset) do diff --git a/lib/atomic_web/live/profile_live/form_component.ex b/lib/atomic_web/live/profile_live/form_component.ex index 82fe062f4..bc7b4fbe6 100644 --- a/lib/atomic_web/live/profile_live/form_component.ex +++ b/lib/atomic_web/live/profile_live/form_component.ex @@ -2,14 +2,52 @@ defmodule AtomicWeb.ProfileLive.FormComponent do use AtomicWeb, :live_component alias Atomic.Accounts + alias AtomicWeb.Components.ImageUploader + import AtomicWeb.Components.Forms - @extensions_whitelist ~w(.jpg .jpeg .gif .png) + @impl true + def render(assigns) do + ~H""" +
+ <.form :let={f} for={@changeset} id="profile-form" phx-target={@myself} phx-change="validate" phx-submit="save"> + +
+
+ <%= label(f, :name, "Profile Picture", class: "mt-3 mb-1 text-sm font-medium text-gray-700") %> + <.live_component module={ImageUploader} id="uploader-profile-picture" uploads={@uploads} target={@myself} /> +
+ +
+
+ <.inputs_for :let={socials_form} field={f[:socials]}> + <.field field={socials_form[:instagram]} type="text" class="w-full" /> + <.field field={socials_form[:facebook]} type="text" class="w-full" /> + <.field field={socials_form[:x]} type="text" class="w-full" /> + <.field field={f[:tiktok]} type="text" placeholder="TikTok" class="w-full" /> + +
+
+ <.field field={f[:name]} type="text" placeholder="Name" class="w-full" /> + <.field field={f[:phone_number]} type="text" placeholder="Phone Number" class="w-full" /> + <.field field={f[:email]} type="email" placeholder="Email" class="w-full" /> +
+ +
+ <.button size={:md} color={:white} icon="hero-cube" phx-click="submit">Save +
+ +
+ """ + end @impl true def mount(socket) do {:ok, socket - |> allow_upload(:picture, accept: @extensions_whitelist, max_entries: 1)} + |> allow_upload(:image, + accept: Uploaders.ProfilePicture.extension_whitelist(), + max_entries: 1 + )} end @impl true @@ -32,6 +70,7 @@ defmodule AtomicWeb.ProfileLive.FormComponent do {:noreply, assign(socket, :changeset, changeset)} end + @impl true def handle_event("save", %{"user" => user_params}, socket) do user = socket.assigns.user @@ -69,8 +108,8 @@ defmodule AtomicWeb.ProfileLive.FormComponent do defp consume_image_data(socket, user) do consume_uploaded_entries(socket, :image, fn %{path: path}, entry -> - Accounts.update_user(user, %{ - "image" => %Plug.Upload{ + Accounts.update_user_picture(user, %{ + "profile_picture" => %Plug.Upload{ content_type: entry.client_type, filename: entry.client_name, path: path diff --git a/lib/atomic_web/live/profile_live/form_component.html.heex b/lib/atomic_web/live/profile_live/form_component.html.heex deleted file mode 100644 index 6e0705012..000000000 --- a/lib/atomic_web/live/profile_live/form_component.html.heex +++ /dev/null @@ -1,86 +0,0 @@ -
- <.form :let={f} for={@changeset} id="profile-form" phx-target={@myself} phx-change="validate" phx-submit="save"> -
-
- - -
- <%= label(f, :name, class: "mb-1 text-sm font-medium text-gray-700") %> - <%= text_input(f, :name, - required: true, - placeholder: gettext("John Doe"), - class: "relative w-full sm:w-96 appearance-none rounded border border-zinc-300 px-3 py-2 text-zinc-900 placeholder-zinc-500 focus:z-10 focus:border-orange-400 focus:ring-orange-400 focus:outline-none sm:text-sm" - ) %> -
<%= error_tag(f, :name) %>
-
-
- <%= label(f, :email, class: "mb-1 text-sm font-medium text-gray-700") %> - <%= text_input(f, :email, - required: true, - placeholder: gettext("john_doe@mail.com"), - class: "relative w-full sm:w-96 appearance-none rounded border border-zinc-300 px-3 py-2 text-zinc-900 placeholder-zinc-500 focus:z-10 focus:border-orange-400 focus:ring-orange-400 focus:outline-none sm:text-sm" - ) %> -
<%= error_tag(f, :email) %>
-
-
- <%= label(f, :username, class: "mb-1 text-sm font-medium text-gray-700") %> -
- @ - <%= text_input(f, :slug, - required: true, - spellcheck: false, - placeholder: gettext("john_doe"), - class: "pl-0 appearance-none text-zinc-900 placeholder-zinc-500 sm:text-sm border-none w-full focus:outline-none focus:ring-transparent" - ) %> -
-
<%= error_tag(f, :slug) %>
-
-
- <%= label(f, :phone_number, class: "mb-1 text-sm font-medium text-gray-700") %> - <%= text_input(f, :phone_number, - required: true, - placeholder: gettext("912345678"), - class: "relative w-full sm:w-96 appearance-none rounded border border-zinc-300 px-3 py-2 text-zinc-900 placeholder-zinc-500 focus:z-10 focus:border-orange-400 focus:ring-orange-400 focus:outline-none sm:text-sm" - ) %> -
<%= error_tag(f, :phone_number) %>
-
-
- <.live_file_input upload={@uploads.picture} class="hidden" /> - -
-
- <.icon name="hero-camera" class="mx-auto w-12 h-12 sm:w-20 sm:h-20 text-white group-hover:text-opacity-70" /> -
-
-
- <%= for entry <- @uploads.picture.entries do %> - <%= for err <- upload_errors(@uploads.picture, entry) do %> -

<%= Phoenix.Naming.humanize(err) %>

- <% end %> -
-
- <.icon name="hero-camera" class="mx-auto w-12 h-12 sm:w-20 sm:h-20 text-white text-opacity-0 rounded-full group-hover:text-opacity-100" /> -
-
- <.live_img_preview entry={entry} class="object-cover object-center rounded-full w-40 h-40 sm:w-48 sm:h-48 border-4 border-white" /> -
-
- <% end %> -
-
-
-
- <%= submit do %> -
- <.icon name="hero-archive-box-solid" class="mr-2 -ml-1 w-5 h-5" /> Save -
- <% end %> -
- -
diff --git a/lib/atomic_web/live/profile_live/show.ex b/lib/atomic_web/live/profile_live/show.ex index 2ac05c311..a04e74d7d 100644 --- a/lib/atomic_web/live/profile_live/show.ex +++ b/lib/atomic_web/live/profile_live/show.ex @@ -1,8 +1,7 @@ defmodule AtomicWeb.ProfileLive.Show do use AtomicWeb, :live_view - import AtomicWeb.Components.Button - import AtomicWeb.Components.Avatar + import AtomicWeb.Components.{Button, Avatar, Gradient} alias Atomic.Accounts alias Atomic.Organizations diff --git a/lib/atomic_web/live/profile_live/show.html.heex b/lib/atomic_web/live/profile_live/show.html.heex index 60dde0ff6..3b749ec2c 100644 --- a/lib/atomic_web/live/profile_live/show.html.heex +++ b/lib/atomic_web/live/profile_live/show.html.heex @@ -1,14 +1,56 @@ -
-
-
-
-
-

- <%= @user.name %> -

+
+
+ <.gradient class="h-64 w-full bg-cover bg-center" seed={@user.id} /> +
+ +
+
+ +
+
+ <.avatar name={@user.name} color={:light_gray} class="h-36 w-36 text-4xl rounded-full border-4 border-white" type={:user} src={Uploaders.ProfilePicture.url({@user.profile_picture, @user}, :original)} /> +
+
+
+ +

+ <%= @user.name %> +

+ +
+ <%= if length(@organizations) > 0 do %> +
+ <%= for organization <- @organizations do %> +

+ <%= organization.name %> - <%= Atomic.Organizations.get_role(@user.id, organization.id) %> +

+ <% end %> +
+ <% else %> +

No organizations found.

+ <% end %> +
+ +
+
+ TikTok + <.link class="text-blue-500">Tik Tok +
+
+ Instagram + <.link class="text-blue-500">Instagram +
+
+ Facebook + <.link class="text-blue-500">Facebook +
+
+ X + <.link class="text-blue-500">X +
-

@<%= @user.slug %>

-
+ +
<%= if @user.email do %>
Email
@@ -31,18 +73,15 @@
<% end %>
+ + <%= if @is_current_user do %> +
+ <.button patch={Routes.profile_edit_path(@socket, :edit, @user)}> + <%= gettext("Edit") %> + +
+ <% end %>
- <.avatar class="sm:w-44 sm:h-44 sm:text-6xl" name={@user.name} size={:xl} color={:light_gray} />
- -
- - <%= if @is_current_user do %> -
- <.button patch={Routes.profile_edit_path(@socket, :edit, @user)}> - <%= gettext("Edit") %> - -
- <% end %>
From ea9e7cc44468e7881ca663777a394ea17a4cc339 Mon Sep 17 00:00:00 2001 From: Afonso Martins Date: Mon, 23 Sep 2024 19:48:58 +0100 Subject: [PATCH 02/13] fix: save redirect --- lib/atomic_web/live/profile_live/form_component.ex | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/atomic_web/live/profile_live/form_component.ex b/lib/atomic_web/live/profile_live/form_component.ex index bc7b4fbe6..59930a199 100644 --- a/lib/atomic_web/live/profile_live/form_component.ex +++ b/lib/atomic_web/live/profile_live/form_component.ex @@ -33,7 +33,7 @@ defmodule AtomicWeb.ProfileLive.FormComponent do
- <.button size={:md} color={:white} icon="hero-cube" phx-click="submit">Save + <.button size={:md} color={:white} icon="hero-cube">Save
@@ -99,7 +99,14 @@ defmodule AtomicWeb.ProfileLive.FormComponent do {:noreply, socket |> put_flash(:success, flash_text) - |> push_navigate(to: Routes.profile_show_path(socket, :show, user_params["slug"]))} + |> push_navigate( + to: + Routes.profile_show_path( + socket, + :show, + user_params["slug"] || socket.assigns.user.slug + ) + )} {:error, %Ecto.Changeset{} = changeset} -> {:noreply, assign(socket, :changeset, changeset)} From 7063235d8b0c79efa09281031235efa58b9923f9 Mon Sep 17 00:00:00 2001 From: Afonso Martins Date: Tue, 24 Sep 2024 11:07:12 +0100 Subject: [PATCH 03/13] Fix: save redirect Tiktok --- lib/atomic_web/live/profile_live/form_component.ex | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/atomic_web/live/profile_live/form_component.ex b/lib/atomic_web/live/profile_live/form_component.ex index 59930a199..8f4872f8e 100644 --- a/lib/atomic_web/live/profile_live/form_component.ex +++ b/lib/atomic_web/live/profile_live/form_component.ex @@ -20,16 +20,16 @@ defmodule AtomicWeb.ProfileLive.FormComponent do
<.inputs_for :let={socials_form} field={f[:socials]}> - <.field field={socials_form[:instagram]} type="text" class="w-full" /> - <.field field={socials_form[:facebook]} type="text" class="w-full" /> - <.field field={socials_form[:x]} type="text" class="w-full" /> - <.field field={f[:tiktok]} type="text" placeholder="TikTok" class="w-full" /> + <.field field={socials_form[:instagram]} type="text" placeholder="Instagram" class="w-full" /> + <.field field={socials_form[:facebook]} type="text" placeholder="Facebook" class="w-full" /> + <.field field={socials_form[:x]} type="text" placeholder="X" class="w-full" /> + <.field field={socials_form[:tiktok]} type="text" placeholder="TikTok" class="w-full" />
+ <.field field={f[:name]} type="text" placeholder="Name" class="w-full" /> + <.field field={f[:phone_number]} type="text" placeholder="Phone Number" class="w-full" /> + <.field field={f[:email]} type="email" placeholder="Email" class="w-full" />
- <.field field={f[:name]} type="text" placeholder="Name" class="w-full" /> - <.field field={f[:phone_number]} type="text" placeholder="Phone Number" class="w-full" /> - <.field field={f[:email]} type="email" placeholder="Email" class="w-full" />
From 90093c915d0b5a17ab93325fc8fd325570b275a7 Mon Sep 17 00:00:00 2001 From: Afonso Martins Date: Tue, 24 Sep 2024 11:08:33 +0100 Subject: [PATCH 04/13] Chore: improve layout of profile page --- .../live/profile_live/show.html.heex | 44 ++++++++++++------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/lib/atomic_web/live/profile_live/show.html.heex b/lib/atomic_web/live/profile_live/show.html.heex index 3b749ec2c..f0c24828a 100644 --- a/lib/atomic_web/live/profile_live/show.html.heex +++ b/lib/atomic_web/live/profile_live/show.html.heex @@ -31,24 +31,34 @@ <% end %>
-
-
- TikTok - <.link class="text-blue-500">Tik Tok + <%= if @user.socials do %> +
+ <%= if @user.socials.tiktok do %> +
+ TikTok + <.link class="text-blue-500" href={"https://tiktok.com/" <> @user.socials.tiktok}>Tik Tok +
+ <% end %> + <%= if @user.socials.instagram do %> +
+ Instagram + <.link class="text-blue-500" href={"https://instagram.com/" <> @user.socials.instagram}>Instagram +
+ <% end %> + <%= if @user.socials.facebook do %> +
+ Facebook + <.link class="text-blue-500" href={"https://facebook.com/" <> @user.socials.facebook}>Facebook +
+ <% end %> + <%= if @user.socials.x do %> +
+ X + <.link class="text-blue-500" href={"https://x.com/" <> @user.socials.x}>X +
+ <% end %>
-
- Instagram - <.link class="text-blue-500">Instagram -
-
- Facebook - <.link class="text-blue-500">Facebook -
-
- X - <.link class="text-blue-500">X -
-
+ <% end %>
<%= if @user.email do %> From 0bab33d0a0a5e373b015dfe30168a5b9b199171c Mon Sep 17 00:00:00 2001 From: Afonso Martins Date: Tue, 24 Sep 2024 20:07:05 +0100 Subject: [PATCH 05/13] Feat: Improve html --- .../live/profile_live/form_component.ex | 28 ++++++++++++------- .../live/profile_live/show.html.heex | 10 +++---- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/lib/atomic_web/live/profile_live/form_component.ex b/lib/atomic_web/live/profile_live/form_component.ex index 8f4872f8e..e1184b64d 100644 --- a/lib/atomic_web/live/profile_live/form_component.ex +++ b/lib/atomic_web/live/profile_live/form_component.ex @@ -10,15 +10,26 @@ defmodule AtomicWeb.ProfileLive.FormComponent do ~H"""
<.form :let={f} for={@changeset} id="profile-form" phx-target={@myself} phx-change="validate" phx-submit="save"> - -
-
+ +
+ +
<%= label(f, :name, "Profile Picture", class: "mt-3 mb-1 text-sm font-medium text-gray-700") %> - <.live_component module={ImageUploader} id="uploader-profile-picture" uploads={@uploads} target={@myself} /> + +
+ <.live_component module={ImageUploader} id="uploader-profile-picture" uploads={@uploads} target={@myself} /> +
- -
-
+ +
+ +
+ <.field field={f[:name]} type="text" placeholder="Name" class="w-full" /> + <.field field={f[:phone_number]} type="text" placeholder="Phone Number" class="w-full" /> + <.field field={f[:email]} type="email" placeholder="Email" class="w-full" /> +
+ +
<.inputs_for :let={socials_form} field={f[:socials]}> <.field field={socials_form[:instagram]} type="text" placeholder="Instagram" class="w-full" /> <.field field={socials_form[:facebook]} type="text" placeholder="Facebook" class="w-full" /> @@ -26,9 +37,6 @@ defmodule AtomicWeb.ProfileLive.FormComponent do <.field field={socials_form[:tiktok]} type="text" placeholder="TikTok" class="w-full" />
- <.field field={f[:name]} type="text" placeholder="Name" class="w-full" /> - <.field field={f[:phone_number]} type="text" placeholder="Phone Number" class="w-full" /> - <.field field={f[:email]} type="email" placeholder="Email" class="w-full" />
diff --git a/lib/atomic_web/live/profile_live/show.html.heex b/lib/atomic_web/live/profile_live/show.html.heex index f0c24828a..fe94ab368 100644 --- a/lib/atomic_web/live/profile_live/show.html.heex +++ b/lib/atomic_web/live/profile_live/show.html.heex @@ -8,7 +8,7 @@
- <.avatar name={@user.name} color={:light_gray} class="h-36 w-36 text-4xl rounded-full border-4 border-white" type={:user} src={Uploaders.ProfilePicture.url({@user.profile_picture, @user}, :original)} /> + <.avatar name={@user.name} color={:light_gray} class="h-36 w-36 text-4xl rounded-full border-4 border-white" type={:user} src={Uploaders.ProfilePicture.url({@user.profile_picture, @user}, :originaQl)} />
@@ -36,25 +36,25 @@ <%= if @user.socials.tiktok do %>
TikTok - <.link class="text-blue-500" href={"https://tiktok.com/" <> @user.socials.tiktok}>Tik Tok + <.link class="text-blue-500" target="_blank" href={"https://tiktok.com/" <> @user.socials.tiktok}>Tik Tok
<% end %> <%= if @user.socials.instagram do %>
Instagram - <.link class="text-blue-500" href={"https://instagram.com/" <> @user.socials.instagram}>Instagram + <.link class="text-blue-500" target="_blank" href={"https://instagram.com/" <> @user.socials.instagram}>Instagram
<% end %> <%= if @user.socials.facebook do %>
Facebook - <.link class="text-blue-500" href={"https://facebook.com/" <> @user.socials.facebook}>Facebook + <.link class="text-blue-500" target="_blank" href={"https://facebook.com/" <> @user.socials.facebook}>Facebook
<% end %> <%= if @user.socials.x do %>
X - <.link class="text-blue-500" href={"https://x.com/" <> @user.socials.x}>X + <.link class="text-blue-500" target="_blank" href={"https://x.com/" <> @user.socials.x}>X
<% end %>
From 7cc2a0057a0c1f56de0e648ce8026012969e22dc Mon Sep 17 00:00:00 2001 From: Afonso Martins Date: Tue, 24 Sep 2024 20:17:11 +0100 Subject: [PATCH 06/13] misspell --- lib/atomic_web/live/profile_live/show.html.heex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/atomic_web/live/profile_live/show.html.heex b/lib/atomic_web/live/profile_live/show.html.heex index fe94ab368..dcbff86f2 100644 --- a/lib/atomic_web/live/profile_live/show.html.heex +++ b/lib/atomic_web/live/profile_live/show.html.heex @@ -8,7 +8,7 @@
- <.avatar name={@user.name} color={:light_gray} class="h-36 w-36 text-4xl rounded-full border-4 border-white" type={:user} src={Uploaders.ProfilePicture.url({@user.profile_picture, @user}, :originaQl)} /> + <.avatar name={@user.name} color={:light_gray} class="h-36 w-36 text-4xl rounded-full border-4 border-white" type={:user} src={Uploaders.ProfilePicture.url({@user.profile_picture, @user}, :original)} />
From 95cbd6a9b93a7d5cf405b42e5537725f307f4ae4 Mon Sep 17 00:00:00 2001 From: Afonso Martins Date: Wed, 25 Sep 2024 18:24:34 +0100 Subject: [PATCH 07/13] Fix: Profile Picture upload --- lib/atomic/accounts.ex | 4 +++- lib/atomic_web/components/sidebar.ex | 7 ++++--- .../live/profile_live/form_component.ex | 18 +++--------------- 3 files changed, 10 insertions(+), 19 deletions(-) diff --git a/lib/atomic/accounts.ex b/lib/atomic/accounts.ex index 97b67564c..9396fac3c 100644 --- a/lib/atomic/accounts.ex +++ b/lib/atomic/accounts.ex @@ -485,6 +485,7 @@ defmodule Atomic.Accounts do def update_user_picture(%User{} = user, attrs \\ %{}) do user |> User.picture_changeset(attrs) + |> IO.inspect() |> Repo.update() end @@ -500,10 +501,11 @@ defmodule Atomic.Accounts do {:error, %Ecto.Changeset{}} """ - def update_user(%User{} = user, attrs \\ %{}, _after_save \\ &{:ok, &1}) do + def update_user(%User{} = user, attrs \\ %{}, after_save \\ &{:ok, &1}) do user |> User.changeset(attrs) |> Repo.update() + |> after_save(after_save) end @doc """ diff --git a/lib/atomic_web/components/sidebar.ex b/lib/atomic_web/components/sidebar.ex index 23277ee1b..eea8310c7 100644 --- a/lib/atomic_web/components/sidebar.ex +++ b/lib/atomic_web/components/sidebar.ex @@ -5,6 +5,7 @@ defmodule AtomicWeb.Components.Sidebar do alias Phoenix.LiveView.JS import AtomicWeb.Components.Icon alias Atomic.Organizations + import AtomicWeb.Components.Avatar attr :current_user, :map, required: true attr :current_organization, :map, required: true @@ -122,7 +123,7 @@ defmodule AtomicWeb.Components.Sidebar do <:wrapper> @@ -190,9 +191,9 @@ defmodule AtomicWeb.Components.Sidebar do defp user_image(user) do if user.profile_picture do - Uploaders.ProfilePicture.url({user, user.profile_picture}, :original) + Atomic.Uploaders.ProfilePicture.url({user, user.profile_picture}, :original) else - nil + "" end end diff --git a/lib/atomic_web/live/profile_live/form_component.ex b/lib/atomic_web/live/profile_live/form_component.ex index e1184b64d..7483eb94c 100644 --- a/lib/atomic_web/live/profile_live/form_component.ex +++ b/lib/atomic_web/live/profile_live/form_component.ex @@ -13,12 +13,9 @@ defmodule AtomicWeb.ProfileLive.FormComponent do
-
+
<%= label(f, :name, "Profile Picture", class: "mt-3 mb-1 text-sm font-medium text-gray-700") %> - -
- <.live_component module={ImageUploader} id="uploader-profile-picture" uploads={@uploads} target={@myself} /> -
+ <.live_component module={ImageUploader} id="uploader-profile-picture" uploads={@uploads} target={@myself} />
@@ -48,22 +45,13 @@ defmodule AtomicWeb.ProfileLive.FormComponent do """ end - @impl true - def mount(socket) do - {:ok, - socket - |> allow_upload(:image, - accept: Uploaders.ProfilePicture.extension_whitelist(), - max_entries: 1 - )} - end - @impl true def update(%{user: user} = assigns, socket) do changeset = Accounts.change_user(user) {:ok, socket + |> allow_upload(:image, accept: Uploaders.ProfilePicture.extension_whitelist(), max_entries: 1) |> assign(assigns) |> assign(:changeset, changeset)} end From ad5460f65f44eeeb5ac74683d717f7327e02d25a Mon Sep 17 00:00:00 2001 From: Afonso Martins Date: Thu, 26 Sep 2024 11:27:32 +0100 Subject: [PATCH 08/13] format code --- lib/atomic_web/live/profile_live/form_component.ex | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/atomic_web/live/profile_live/form_component.ex b/lib/atomic_web/live/profile_live/form_component.ex index 7483eb94c..6a2a1b92a 100644 --- a/lib/atomic_web/live/profile_live/form_component.ex +++ b/lib/atomic_web/live/profile_live/form_component.ex @@ -13,7 +13,7 @@ defmodule AtomicWeb.ProfileLive.FormComponent do
-
+
<%= label(f, :name, "Profile Picture", class: "mt-3 mb-1 text-sm font-medium text-gray-700") %> <.live_component module={ImageUploader} id="uploader-profile-picture" uploads={@uploads} target={@myself} />
@@ -51,7 +51,10 @@ defmodule AtomicWeb.ProfileLive.FormComponent do {:ok, socket - |> allow_upload(:image, accept: Uploaders.ProfilePicture.extension_whitelist(), max_entries: 1) + |> allow_upload(:image, + accept: Uploaders.ProfilePicture.extension_whitelist(), + max_entries: 1 + ) |> assign(assigns) |> assign(:changeset, changeset)} end From 07b311119bebc64dc35068f507f984c1dbf2f541 Mon Sep 17 00:00:00 2001 From: Afonso Martins Date: Tue, 1 Oct 2024 15:38:14 +0100 Subject: [PATCH 09/13] feat: preview profile image in edit page --- lib/atomic_web/live/profile_live/form_component.ex | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/lib/atomic_web/live/profile_live/form_component.ex b/lib/atomic_web/live/profile_live/form_component.ex index 6a2a1b92a..12e726355 100644 --- a/lib/atomic_web/live/profile_live/form_component.ex +++ b/lib/atomic_web/live/profile_live/form_component.ex @@ -4,6 +4,7 @@ defmodule AtomicWeb.ProfileLive.FormComponent do alias Atomic.Accounts alias AtomicWeb.Components.ImageUploader import AtomicWeb.Components.Forms + import AtomicWeb.Components.{Button, Avatar} @impl true def render(assigns) do @@ -14,10 +15,17 @@ defmodule AtomicWeb.ProfileLive.FormComponent do
- <%= label(f, :name, "Profile Picture", class: "mt-3 mb-1 text-sm font-medium text-gray-700") %> - <.live_component module={ImageUploader} id="uploader-profile-picture" uploads={@uploads} target={@myself} /> + <%= if @user.profile_picture != NULL do %> + <%= label(f, :name, "Profile Picture", class: "mt-3 mb-1 text-sm font-medium text-gray-700") %> +
+ <.avatar name={@user.name} color={:light_gray} class="h-36 w-36 rounded-full border-4 border-white text-4xl" type={:user} src={Uploaders.ProfilePicture.url({@user.profile_picture, @user}, :original)} /> +
+ <.live_component module={ImageUploader} id="uploader-profile-picture" uploads={@uploads} target={@myself} /> + <% else %> + <%= label(f, :name, "Profile Picture", class: "mt-3 mb-1 text-sm font-medium text-gray-700") %> + <.live_component module={ImageUploader} id="uploader-profile-picture" uploads={@uploads} target={@myself} /> + <% end %>
-
From da8d768f5e2947febff3faab87363af4f5c2170e Mon Sep 17 00:00:00 2001 From: Afonso Martins Date: Tue, 1 Oct 2024 15:57:50 +0100 Subject: [PATCH 10/13] fix: miss div --- lib/atomic_web/live/profile_live/show.html.heex | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/atomic_web/live/profile_live/show.html.heex b/lib/atomic_web/live/profile_live/show.html.heex index 7f66ffb66..ea54f1c04 100644 --- a/lib/atomic_web/live/profile_live/show.html.heex +++ b/lib/atomic_web/live/profile_live/show.html.heex @@ -103,4 +103,5 @@
<% end %> +
From 1854bf23d4ee0166573255b8e88357f5b0e1ca1d Mon Sep 17 00:00:00 2001 From: Afonso Martins Date: Thu, 3 Oct 2024 19:05:04 +0100 Subject: [PATCH 11/13] feat: add slug field --- lib/atomic_web/components/sidebar.ex | 4 ++-- lib/atomic_web/live/profile_live/form_component.ex | 7 ++++--- lib/atomic_web/live/profile_live/show.html.heex | 11 ----------- .../20221014155230_create_users_auth_tables.exs | 2 ++ 4 files changed, 8 insertions(+), 16 deletions(-) diff --git a/lib/atomic_web/components/sidebar.ex b/lib/atomic_web/components/sidebar.ex index 2a1ef7d45..818412d1b 100644 --- a/lib/atomic_web/components/sidebar.ex +++ b/lib/atomic_web/components/sidebar.ex @@ -191,9 +191,9 @@ defmodule AtomicWeb.Components.Sidebar do defp user_image(user) do if user.profile_picture do - Atomic.Uploaders.ProfilePicture.url({user, user.profile_picture}, :original) + Atomic.Uploaders.ProfilePicture.url({user.profile_picture, user}, :original) else - "" + nil end end diff --git a/lib/atomic_web/live/profile_live/form_component.ex b/lib/atomic_web/live/profile_live/form_component.ex index 8b1b50774..13f782021 100644 --- a/lib/atomic_web/live/profile_live/form_component.ex +++ b/lib/atomic_web/live/profile_live/form_component.ex @@ -15,7 +15,7 @@ defmodule AtomicWeb.ProfileLive.FormComponent do
- <%= if @user.profile_picture != NULL do %> + <%= if @user.profile_picture != nil do %> <%= label(f, :name, "Profile Picture", class: "mt-3 mb-1 text-sm font-medium text-gray-700") %>
<.avatar name={@user.name} color={:light_gray} class="h-36 w-36 rounded-full border-4 border-white text-4xl" type={:user} src={Uploaders.ProfilePicture.url({@user.profile_picture, @user}, :original)} /> @@ -28,10 +28,11 @@ defmodule AtomicWeb.ProfileLive.FormComponent do
-
+
<.field field={f[:name]} type="text" placeholder="Name" class="w-full" /> <.field field={f[:phone_number]} type="text" placeholder="Phone Number" class="w-full" /> <.field field={f[:email]} type="email" placeholder="Email" class="w-full" /> + <.field field={f[:slug]} type="text" placeholder="User Name" class="w-full" />
@@ -106,7 +107,7 @@ defmodule AtomicWeb.ProfileLive.FormComponent do {:noreply, socket |> put_flash(:success, flash_text) - |> push_navigate(to: ~p"/profile/#{user_params["slug"]}")} + |> push_navigate(to: ~p"/profile/#{user_params["slug"] || user.slug}")} {:error, %Ecto.Changeset{} = changeset} -> {:noreply, assign(socket, :changeset, changeset)} diff --git a/lib/atomic_web/live/profile_live/show.html.heex b/lib/atomic_web/live/profile_live/show.html.heex index ea54f1c04..8ded76bff 100644 --- a/lib/atomic_web/live/profile_live/show.html.heex +++ b/lib/atomic_web/live/profile_live/show.html.heex @@ -83,19 +83,8 @@
<% end %>
- - <%= if @is_current_user do %> -
- <.button patch={Routes.profile_edit_path(@socket, :edit, @user)}> - <%= gettext("Edit") %> - -
- <% end %>
- -
- <%= if @is_current_user do %>
<.button patch={~p"/profile/#{@user}/edit"}> diff --git a/priv/repo/migrations/20221014155230_create_users_auth_tables.exs b/priv/repo/migrations/20221014155230_create_users_auth_tables.exs index dc00ab854..5205f706d 100644 --- a/priv/repo/migrations/20221014155230_create_users_auth_tables.exs +++ b/priv/repo/migrations/20221014155230_create_users_auth_tables.exs @@ -12,6 +12,8 @@ defmodule Atomic.Repo.Migrations.CreateUsersAuthTables do add :slug, :citext add :role, :string, null: false, default: "student" + add :socials, :map + add :hashed_password, :string, null: false add :confirmed_at, :naive_datetime From e9c9aec1758cfa0f2c2a9e97c87aaf32eb504129 Mon Sep 17 00:00:00 2001 From: Afonso Martins Date: Thu, 3 Oct 2024 19:08:31 +0100 Subject: [PATCH 12/13] fix: delete IO --- lib/atomic/accounts.ex | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/atomic/accounts.ex b/lib/atomic/accounts.ex index 6a2bd0d49..b822aa2d1 100644 --- a/lib/atomic/accounts.ex +++ b/lib/atomic/accounts.ex @@ -476,7 +476,6 @@ defmodule Atomic.Accounts do def update_user_picture(%User{} = user, attrs \\ %{}) do user |> User.picture_changeset(attrs) - |> IO.inspect() |> Repo.update() end From 85b8d58cdc62c51774623b2d84e58872ade4edb9 Mon Sep 17 00:00:00 2001 From: Afonso Martins Date: Thu, 3 Oct 2024 19:14:54 +0100 Subject: [PATCH 13/13] feat: pass checks --- lib/atomic_web/components/sidebar.ex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/atomic_web/components/sidebar.ex b/lib/atomic_web/components/sidebar.ex index 818412d1b..4c11f6fd4 100644 --- a/lib/atomic_web/components/sidebar.ex +++ b/lib/atomic_web/components/sidebar.ex @@ -5,7 +5,7 @@ defmodule AtomicWeb.Components.Sidebar do alias Phoenix.LiveView.JS import AtomicWeb.Components.Icon alias Atomic.Organizations - import AtomicWeb.Components.Avatar + alias Atomic.Uploaders.ProfilePicture attr :current_user, :map, required: true attr :current_organization, :map, required: true @@ -191,7 +191,7 @@ defmodule AtomicWeb.Components.Sidebar do defp user_image(user) do if user.profile_picture do - Atomic.Uploaders.ProfilePicture.url({user.profile_picture, user}, :original) + ProfilePicture.url({user.profile_picture, user}, :original) else nil end