Skip to content

Commit

Permalink
User profile page: basic info form (#2470)
Browse files Browse the repository at this point in the history
* Add basic info form to the profile page and update forms to use new inputs
* Disable save button when no changes detected in the form
* Test update basic user information
* Tooltip on select box for contact pref


---------

Co-authored-by: Stuart Corbishley <[email protected]>
  • Loading branch information
elias-ba and stuartc authored Sep 11, 2024
1 parent f326807 commit 0eb3b91
Show file tree
Hide file tree
Showing 8 changed files with 266 additions and 105 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ and this project adheres to

### Changed

- Enhance user profile page to add a section for updating basic information
[#2470](https://github.com/OpenFn/lightning/pull/2470)
- Upgraded Heroicons to v2.1.5, from v2.0.18
[#2483](https://github.com/OpenFn/lightning/pull/2483)
- Standardize `link-uuid` style for uuid chips
Expand Down
10 changes: 9 additions & 1 deletion lib/lightning/accounts.ex
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,14 @@ defmodule Lightning.Accounts do
|> Repo.update()
end

def change_user_info(%User{} = user, attrs \\ %{}) do
User.info_changeset(user, attrs)
end

def update_user_info(%User{} = user, attrs) do
change_user_info(user, attrs) |> Repo.update()
end

## Settings

@doc """
Expand Down Expand Up @@ -510,7 +518,7 @@ defmodule Lightning.Accounts do
)
end

def validate_change_user_email(user, params) do
def validate_change_user_email(user, params \\ %{}) do
data = %{email: nil, current_password: nil}
types = %{email: :string, current_password: :string}

Expand Down
14 changes: 14 additions & 0 deletions lib/lightning/accounts/user.ex
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,20 @@ defmodule Lightning.Accounts.User do
|> validate_role()
end

@doc """
A user changeset for basic information:
- first_name
- last_name
- contact_preference
"""
def info_changeset(user, attrs) do
user
|> cast(attrs, [:first_name, :last_name, :contact_preference])
|> validate_name()
|> trim_name()
end

@doc """
A user changeset for changing the email.
Expand Down
21 changes: 21 additions & 0 deletions lib/lightning_web/components/new_inputs.ex
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,24 @@ defmodule LightningWeb.Components.NewInputs do
"""
end

attr :id, :string, required: true
attr :tooltip, :string, required: true
attr :class, :string, default: ""
attr :icon, :string, default: "hero-information-circle-solid"
attr :icon_class, :string, default: "w-4 h-4 text-primary-600 opacity-50"

defp tooltip_for_label(assigns) do
classes = ~w"relative cursor-pointer"

assigns = assign(assigns, class: classes ++ List.wrap(assigns.class))

~H"""
<span class={@class} id={@id} aria-label={@tooltip} phx-hook="Tooltip">
<.icon name={@icon} class={@icon_class} />
</span>
"""
end

@doc """
Renders an input with label and error messages.
Expand Down Expand Up @@ -154,6 +172,8 @@ defmodule LightningWeb.Components.NewInputs do

attr :display_errors, :boolean, default: true

attr :tooltip, :any, default: nil

slot :inner_block

def input(%{field: %Phoenix.HTML.FormField{} = field} = assigns) do
Expand Down Expand Up @@ -215,6 +235,7 @@ defmodule LightningWeb.Components.NewInputs do
:if={Map.get(@rest, :required, false)}
class="text-red-500"
> *</span>
<.tooltip_for_label :if={@tooltip} id={@id} tooltip={@tooltip} />
</.label>
<div class="flex w-full">
<div class="relative items-center">
Expand Down
2 changes: 1 addition & 1 deletion lib/lightning_web/live/profile_live/edit.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<%= @current_user.first_name %> <%= @current_user.last_name %>
</h2>
<p class="mt-1 text-sm leading-6 text-gray-600">
Change email, change password, and request deletion.
Change name, email, password, and request deletion.
</p>
<div class="border-b border-gray-900/10 mt-6 mb-6" />
<p class="mt-1 text-sm leading-6 text-gray-600">
Expand Down
42 changes: 39 additions & 3 deletions lib/lightning_web/live/profile_live/form_component.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ defmodule LightningWeb.ProfileLive.FormComponent do
{:ok,
socket
|> assign(
password_changeset: Accounts.change_user_password(user),
email_changeset: user |> Accounts.validate_change_user_email(%{}),
user: user,
action: action
action: action,
email_changeset: Accounts.validate_change_user_email(user),
password_changeset: Accounts.change_user_password(user),
user_info_changeset: Accounts.change_user_info(user)
)}
end

Expand Down Expand Up @@ -71,6 +72,20 @@ defmodule LightningWeb.ProfileLive.FormComponent do
end
end

@impl true
def handle_event("update_basic_info", %{"user" => user_params}, socket) do
case Accounts.update_user_info(socket.assigns.user, user_params) do
{:ok, _} ->
{:noreply,
socket
|> put_flash(:info, "User information updated successfully")
|> push_navigate(to: ~p"/profile")}

{:error, changeset} ->
{:noreply, assign(socket, :user_info_changeset, changeset)}
end
end

@impl true
def handle_event("validate_password", %{"user" => user_params}, socket) do
changeset =
Expand All @@ -90,4 +105,25 @@ defmodule LightningWeb.ProfileLive.FormComponent do

{:noreply, assign(socket, :email_changeset, changeset)}
end

@impl true
def handle_event("validate_basic_info", %{"user" => user_params}, socket) do
changeset =
socket.assigns.user
|> Accounts.change_user_info(user_params)
|> Map.put(:action, :validate)

{:noreply, assign(socket, :user_info_changeset, changeset)}
end

def enum_options(module, field) do
value_label_map = %{
critical: "Critical",
any: "Anytime"
}

module
|> Ecto.Enum.values(field)
|> Enum.map(&{Map.get(value_label_map, &1, to_string(&1)), &1})
end
end
Loading

0 comments on commit 0eb3b91

Please sign in to comment.