friends/friends/lib/friends_web/live/edit.ex
2022-11-23 13:59:17 -05:00

178 lines
5.1 KiB
Elixir

defmodule FriendsWeb.FriendsLive.Edit do
use FriendsWeb, :live_view
import FriendsWeb.LiveHelpers
import FriendsWeb.FriendsLive.Components
import Helpers
import Helpers.Names
alias Friends.{Friend, Places}
# No slug means it's a new profile form
def mount(%{}, token, socket) do
friend = Friend.new()
live_action = socket.assigns.live_action || :overview
{:ok,
socket
|> assign(:live_action, live_action)
|> assign_current_user(token |> Map.get("user_token"))
|> assign(:friend, friend)
|> assign(:address_latlon, nil)
|> assign(:search_results, nil)
|> title("Welcome")
|> assign(:changeset, %Friend{} |> Friend.changeset())}
end
# Has a slug means it's an edit profile form
def mount(%{"slug" => slug} = _attrs, token, socket) do
live_action = socket.assigns.live_action || :overview
friend = Friend.get_by_slug(slug)
if(live_action) do
{:ok,
socket
|> assign(:live_action, live_action)
|> assign_current_user(token |> Map.get("user_token"))
|> assign(:friend, friend)
|> assign(:action, Routes.friends_path(socket, :update))
|> title(friend.name <> " - " <> (live_action |> titlecase))
|> assign(:changeset, %Friend{} |> Friend.changeset())
|> assign(:address_query, nil)
|> assign(:search_results, nil)}
else
{:ok, socket |> redirect(to: Routes.friends_show_path(socket, :overview, friend.slug))}
end
end
def handle_params(%{"slug" => slug} = _attrs, _url, socket) do
live_action = socket.assigns.live_action || false
friend = Friend.get_by_slug(slug)
editable = friend |> Friend.can_be_edited_by(socket.assigns[:current_user])
{address_latlon, address_query} = friend |> Friend.get_address()
{:noreply,
socket
|> assign_friend(friend)
|> assign(:action, Routes.friends_path(socket, :update))
|> assign(:live_action, live_action)
|> assign(:address_query, address_query)
|> assign(:address_latlon, address_latlon |> Poison.encode!())
|> assign(:search_results, nil)
|> title(friend.name <> " - " <> (live_action |> titlecase))
|> assign(:editable, editable)}
end
def handle_params(_attrs, _token, socket) do
friend = Friend.new()
{:noreply,
socket
|> assign_friend(friend)
|> assign(:live_action, socket.assigns.live_action)
|> assign(:address_query, nil)
|> assign(:action, Routes.friends_path(socket, :update))
|> title("Welcome")}
end
def handle_event("validate", %{"friend" => form_params}, %{assigns: %{friend: friend}} = socket) do
id = form_params["id"] |> parse_id
name = form_params["name"]
nickname = form_params["nickname"]
born = form_params["born"]
email = form_params["email"]
phone = form_params["phone"] |> format_phone
address_query = form_params["address_query"]
address_latlon = form_params["address_latlon"]
new_params = %{
id: id,
name: name,
nickname: nickname,
slug: friend.slug,
born: born,
phone: phone,
email: email
}
changeset =
%Friend{}
|> Friend.changeset(new_params)
|> Map.put(:action, :validate)
{
:noreply,
socket
|> assign(:changeset, changeset)
|> assign_friend(friend |> struct(new_params), changeset)
|> assign(:address_query, address_query)
|> assign(:address_latlon, address_latlon)
}
end
# Handle form saving
def handle_event(
"save",
%{"friend" => form_params},
%{assigns: %{changeset: _changeset}} = socket
) do
name = form_params["name"]
nickname = form_params["nickname"]
born = form_params["born"]
email = form_params["email"]
phone = form_params["phone"] |> format_phone
slug = form_params["slug"] || name |> to_slug
id = form_params["id"] || :new
address_latlon = form_params["address_latlon"] |> Poison.decode!()
address_query = form_params["address_query"]
address = %Friends.Places.Place{
name: address_query,
latlon: address_latlon
}
new_address =
address
|> Friends.Places.Place.get_or_create()
new_params = %{
id: id,
name: name,
nickname: nickname,
slug: slug,
born: born,
phone: phone,
email: email,
address_id: new_address.id
}
updated_friend = Friend.create_or_update(new_params)
new_changeset = updated_friend |> Friend.changeset()
{
:noreply,
socket
|> put_flash(:info, "Saved #{updated_friend |> first_name}!")
|> assign(:new_friend, new_changeset)
|> assign(:friend, updated_friend)
|> push_navigate(to: "/friend/#{updated_friend.slug}")
}
end
def handle_event("address_search", %{"friend" => %{"address_query" => query}}, socket) do
results = Places.Search.autocomplete(query) |> Enum.map(&Places.Search.parse_features/1)
if query == "" do
{:noreply, socket |> assign(:search_results, nil)}
else
{:noreply, socket |> assign(:search_results, results)}
end
end
def handle_event(event, unsigned_params, socket) do
{:noreply, socket}
end
end