defmodule LivebookWeb.UserComponent do use LivebookWeb, :live_component import LivebookWeb.UserComponents alias Livebook.EctoTypes.HexColor alias Livebook.Users @impl true def update(assigns, socket) do socket = assign(socket, assigns) user = socket.assigns.user changeset = Users.change_user(user) {:ok, assign(socket, changeset: changeset, user: user)} end @impl true def render(assigns) do ~H"""

User profile

<.user_avatar user={@user} class="h-20 w-20" text_class="text-3xl" />
<.form :let={f} for={@changeset} phx-submit={@on_save |> JS.push("save")} phx-change="validate" phx-target={@myself} id="user_form" phx-hook="UserForm" >
<.text_field field={f[:name]} label="Display name" spellcheck="false" disabled={Livebook.Config.identity_provider_read_only?()} /> <%= if @user.email do %> <.text_field field={f[:email]} label="email" spellcheck="false" disabled="true" /> <% end %> <.hex_color_field field={f[:hex_color]} label="Cursor color" randomize={JS.push("randomize_color", target: @myself)} /> <.button type="submit" disabled={not @changeset.valid?}> <.remix_icon icon="save-line" /> Save
""" end @impl true def handle_event("randomize_color", %{}, socket) do hex_color = HexColor.random(except: [socket.assigns.user.hex_color]) handle_event("validate", %{"user" => %{"hex_color" => hex_color}}, socket) end def handle_event("validate", %{"user" => params}, socket) do changeset = socket.assigns.user |> Users.change_user(params) |> Map.put(:action, :validate) user = if changeset.valid? do Ecto.Changeset.apply_action!(changeset, :update) else socket.assigns.user end {:noreply, assign(socket, changeset: changeset, user: user)} end def handle_event("save", %{"user" => params}, socket) do case Users.update_user(socket.assigns.user, params) do {:ok, user} -> {:noreply, assign(socket, changeset: Users.change_user(user), user: user)} {:error, changeset} -> {:noreply, assign(socket, changeset: changeset)} end end end