diff --git a/lib/chiya/accounts.ex b/lib/chiya/accounts.ex index d0664bd..40c0dd9 100644 --- a/lib/chiya/accounts.ex +++ b/lib/chiya/accounts.ex @@ -116,6 +116,19 @@ defmodule Chiya.Accounts do User.email_changeset(user, attrs, validate_email: false) end + @doc """ + Returns an `%Ecto.Changeset{}` for changing the user profile. + + ## Examples + + iex> change_user_profile(user) + %Ecto.Changeset{data: %User{}} + + """ + def change_user_profile(user, attrs \\ %{}) do + User.profile_changeset(user, attrs) + end + @doc """ Returns an `%Ecto.Changeset{}` for changing the user avatar. @@ -149,6 +162,15 @@ defmodule Chiya.Accounts do |> Ecto.Changeset.apply_action(:update) end + @doc """ + Updates the user profile. + """ + def update_user_profile(user, attrs) do + user + |> User.profile_changeset(attrs) + |> Repo.update() + end + @doc """ Updates the user email using the given token. diff --git a/lib/chiya/accounts/user.ex b/lib/chiya/accounts/user.ex index f25b8d3..8591814 100644 --- a/lib/chiya/accounts/user.ex +++ b/lib/chiya/accounts/user.ex @@ -4,6 +4,10 @@ defmodule Chiya.Accounts.User do import Ecto.Changeset schema "users" do + field :name, :string + field :handle, :string + field :bio, :string + field :email, :string field :password, :string, virtual: true, redact: true field :hashed_password, :string, redact: true @@ -116,6 +120,14 @@ defmodule Chiya.Accounts.User do end end + @doc """ + Returns an `%Ecto.Changeset{}` for tracking user profile changes. + """ + def profile_changeset(user, attrs) do + user + |> cast(attrs, [:name, :handle, :bio]) + end + @doc """ A user changeset for changing the password. diff --git a/lib/chiya_web/live/user_profile_live.ex b/lib/chiya_web/live/user_profile_live.ex index 301c088..1b9ac17 100644 --- a/lib/chiya_web/live/user_profile_live.ex +++ b/lib/chiya_web/live/user_profile_live.ex @@ -13,6 +13,9 @@ defmodule ChiyaWeb.UserProfileLive do <.list> + <:item title="Name"><%= @current_user.name %> + <:item title="Handle"><%= @current_user.handle %> + <:item title="Bio"><%= @current_user.bio %> <:item title="Email"><%= @current_user.email %> """ diff --git a/lib/chiya_web/live/user_settings_live.ex b/lib/chiya_web/live/user_settings_live.ex index 20b53bd..4c03a12 100644 --- a/lib/chiya_web/live/user_settings_live.ex +++ b/lib/chiya_web/live/user_settings_live.ex @@ -29,6 +29,25 @@ defmodule ChiyaWeb.UserSettingsLive do <.line /> + <.header>Change Profile + + <.simple_form + for={@profile_form} + id="profile_form" + phx-submit="update_profile" + phx-change="validate_profile" + > + <.input field={@profile_form[:name]} label="Name" required /> + <.input field={@profile_form[:handle]} label="Handle" required /> + <.input field={@profile_form[:bio]} type="textarea" label="Bio" required /> + + <:actions> + <.button phx-disable-with="Changing...">Change Email + + + + <.line /> + <.header>Change Email <.simple_form @@ -107,6 +126,7 @@ defmodule ChiyaWeb.UserSettingsLive do email_changeset = Accounts.change_user_email(user) password_changeset = Accounts.change_user_password(user) image_changeset = Accounts.change_user_image(user) + profile_changeset = Accounts.change_user_profile(user) socket = socket @@ -116,6 +136,7 @@ defmodule ChiyaWeb.UserSettingsLive do |> assign(:current_email, user.email) |> assign(:email_form, to_form(email_changeset)) |> assign(:password_form, to_form(password_changeset)) + |> assign(:profile_form, to_form(profile_changeset)) |> assign(:image_form, to_form(image_changeset)) |> assign(:trigger_submit, false) |> assign(:uploaded_files, []) @@ -150,6 +171,31 @@ defmodule ChiyaWeb.UserSettingsLive do |> assign(:user, Accounts.get_user!(user.id))} end + def handle_event("validate_profile", params, socket) do + %{"user" => user_params} = params + + profile_form = + socket.assigns.current_user + |> Accounts.change_user_profile(user_params) + |> Map.put(:action, :validate) + |> to_form() + + {:noreply, assign(socket, profile_form: profile_form)} + end + + def handle_event("update_profile", params, socket) do + %{"user" => user_params} = params + user = socket.assigns.current_user + + case Accounts.update_user_profile(user, user_params) do + {:ok, _updated_user} -> + {:noreply, socket |> put_flash(:info, "User updated!")} + + {:error, changeset} -> + {:noreply, assign(socket, :profile_form, to_form(Map.put(changeset, :action, :insert)))} + end + end + def handle_event("validate_email", params, socket) do %{"current_password" => password, "user" => user_params} = params diff --git a/priv/repo/migrations/20230703173933_add_user_fields.exs b/priv/repo/migrations/20230703173933_add_user_fields.exs new file mode 100644 index 0000000..c301e3d --- /dev/null +++ b/priv/repo/migrations/20230703173933_add_user_fields.exs @@ -0,0 +1,11 @@ +defmodule Chiya.Repo.Migrations.AddUserFields do + use Ecto.Migration + + def change do + alter table(:users) do + add :handle, :string + add :name, :string + add :bio, :text + end + end +end