diff --git a/friends/lib/friends/friend.ex b/friends/lib/friends/friend.ex
index 3183e1f..69fe5e3 100644
--- a/friends/lib/friends/friend.ex
+++ b/friends/lib/friends/friend.ex
@@ -153,19 +153,8 @@ defmodule Friends.Friend do
Date.diff(Date.utc_today(), friend.born) |> div(365)
end
- # TODO: Refactor
- def create_birth_event(friend) do
- if is_nil(
- @repo.all(
- from(e in Friends.Event,
- where: e.name == "born"
- )
- )
- |> List.flatten()
- ) do
- else
- "find"
- end
+ def can_be_edited_by(friend, user) do
+ friend.id == user.profile.id
end
def assign_user(%Friend{} = friend) do
diff --git a/friends/lib/friends_web/live/components/components.ex b/friends/lib/friends_web/live/components/components.ex
new file mode 100644
index 0000000..ce9a01a
--- /dev/null
+++ b/friends/lib/friends_web/live/components/components.ex
@@ -0,0 +1,167 @@
+defmodule FriendsWeb.FriendsLive.Components do
+ use FriendsWeb, :live_view
+ use Phoenix.HTML
+ import Helpers
+ alias Friends.Friend
+
+ def show_page("overview", assigns) do
+ ~H"""
+
+
+ Nickname:
+
+ <%= if is_nil(@friend.nickname) do %>
+ none
+ <% else %>
+ <%= @friend.nickname %>
+ <% end %>
+
+
+
+ Birthday:
+ <%= @friend.born |> Calendar.strftime("%B %d, %Y") %>
+
+ (<%= @friend |> Friend.age %> years old)
+
+
+
+ Email:
+ <%= @friend.email %>
+
+
+ Phone:
+ <%= @friend.phone %>
+
+
+ <%= if @friend |> Friend.can_be_edited_by(@current_user) do %>
+
+ <.link patch={"/friend/#{@friend.slug}/#{@page_view}/edit"} class="btn btn-block md:btn-wide text-white">edit
+
+ <% end %>
+ """
+ end
+
+ def show_page("calendar", assigns) do
+ ~H"""
+
+ <%= for event <- @friend |> Friends.Friend.get_events do %>
+
+
+ <%= event.name %>
+
+
+ <% end %>
+ <%= if @friend |> Friends.Friend.get_events |> Enum.empty? do %>
+
None yet.
+ <% end %>
+
+ """
+ end
+
+ def show_page("relationships", assigns) do
+ ~H"""
+
+ <%= for relation <- @friend |> relations do %>
+ <% relationship = relation(@friend, relation) %>
+
+
+
+
+ <%= relation.name %>
+ <%= if relationship |> Friends.Relationship.get_relation do %>
+ Friends.Relationship.get_color}"}><%= relationship |> Friends.Relationship.get_relation %>
+ <% end %>
+
+
If a dog chews shoes whose shoes does he choose?
+
+
+ <% end %>
+ <%= if @friend |> relations |> Enum.empty? do %>
+
No relationships on record yet.
+ <% end %>
+
+
+ <.link patch={"/friend/#{@friend.slug}/update?page=relationships"} class="btn btn-block md:btn-wide text-white">edit
+
+ """
+ end
+
+ ###
+
+ def form_page("overview", assigns) do
+ ~H"""
+ <.form
+ for={@changeset}
+ let={f}
+ action={@action}
+ phx_change= "validate"
+ phx_submit= "save">
+ <%= hidden_input f, :id, value: @friend.id %>
+
+ <%= text_input f, :name, placeholder: "Full Name",
+ class: "m-0 p-0 pb-2 pl-2 input input-bordered border-dashed",
+ style: "color: var(--tw-prose-headings);
+ font-weight: 800;
+ font-size: 2.25em;
+ min-width: 50%;
+ text-indent: 4px;
+ line-height: 1.1111111;",
+ value: @friend.name,
+ phx_debounce: :blur %>
+
<%= error_tag f, :name %>
+
+
+
+ Nickname:
+ <%= text_input f, :nickname, class: "input input-primary input-sm md:input-md", phx_debounce: "blur", value: @friend.nickname %>
+
+
+ Birthday:
+
+ <%= date_input f, :born, class: "input input-primary input-sm md:input-md", phx_debounce: "blur", value: @friend.born %>
+
<%= error_tag f, :born %>
+
+
+
+ Email:
+
+ <%= text_input f, :email, class: "input input-primary input-sm md:input-md", phx_debounce: "blur", value: @friend.email %>
+
<%= error_tag f, :email %>
+
+
+
+ Phone:
+
+ <%= text_input f, :phone, class: "input input-primary input-sm md:input-md", phx_debounce: "blur", value: @friend.phone %>
+
<%= error_tag f, :phone %>
+
+
+
+
+
+
+ """
+ end
+
+ def form_page("relationships", assigns) do
+ ~H"""
+ <%= FriendsWeb.FriendLive.Friend.header(assigns) %>
+ """
+ end
+end
diff --git a/friends/lib/friends_web/live/friend.ex b/friends/lib/friends_web/live/friend.ex
index 8b9e4b4..d789cff 100644
--- a/friends/lib/friends_web/live/friend.ex
+++ b/friends/lib/friends_web/live/friend.ex
@@ -1,158 +1,160 @@
-defmodule FriendsWeb.FriendLive.Friend do
+defmodule FriendsWeb.FriendsLive.Friend do
use FriendsWeb, :live_view
- use Phoenix.HTML
- import Helpers
- import Helpers.Names
- alias Friends.{Friend,Relationship}
+
alias FriendsWeb.FriendLive.Components
alias FriendsWeb.Router.Helpers, as: Routes
+ alias Friends.Friend
+
+ import FriendsWeb.LiveHelpers
+ import Helpers
+ import Helpers.Names
# Initialize variables on first load
- def mount(%{}, _token, socket) do
- {:ok, socket
- |> title("New Friend")
- |> assign(:changeset, %Friend{} |> Friend.changeset)
- }
+ def mount(%{}, token, socket) do
+ {:ok,
+ socket
+ |> title("New Friend")
+ |> assign_current_user(token |> Map.get("user_token"))
+ |> assign(:changeset, %Friend{} |> Friend.changeset())}
end
# Show Friend
- def handle_params(%{"slug" => slug} = attrs, _token, socket) do
+ def handle_params(%{"slug" => slug} = attrs, _url, socket) do
friend = Friend.get_by_slug(slug)
- page = if (attrs |> Map.get("page")) in ["overview", "calendar", "relationships"] do
- attrs["page"]
- else
- "overview"
- end
+ page =
+ if (attrs |> Map.get("page")) in ["overview", "calendar", "relationships"] do
+ attrs["page"]
+ else
+ "redir"
+ end
- {:noreply, socket
- |> title(friend.name <> " - " <> (page |> :string.titlecase()))
- |> assign_friend(friend)
- |> page_view(page)
- |> assign(:action, Routes.friend_path(socket, :update, friend.id))
- }
+ if page == "redir" do
+ {:noreply,
+ socket
+ |> push_patch(to: "/friend/#{slug}/overview")}
+ else
+ {:noreply,
+ socket
+ |> title(friend.name <> " - " <> (page |> :string.titlecase()))
+ |> assign_friend(friend)
+ |> page_view(page)
+ |> assign(:current_user, nil)
+ |> assign(:action, Routes.friend_path(socket, :update, friend.id))}
+ end
end
# New Friend
- def handle_params(attrs, _token, socket) do
- friend = Friend.new
- {:noreply, socket
- |> title("New Friend")
- |> assign_friend(friend)
- |> page_view("overview")
- |> assign(:action,Routes.friend_path(socket, :create))
- }
- end
+ def handle_params(_attrs, _token, socket) do
+ friend = Friend.new()
+ {:noreply,
+ socket
+ |> title("New Friend")
+ |> assign_friend(friend)
+ |> page_view("overview")
+ |> assign(:action, Routes.friend_path(socket, :create))}
+ end
# Handle form validation
def handle_event("validate", %{"friend" => form_params}, %{assigns: %{friend: friend}} = socket) do
+ id = form_params["id"]
+ name = form_params["name"]
+ nickname = form_params["nickname"]
+ born = form_params["born"]
+ email = form_params["email"]
+ phone = form_params["phone"] |> format_phone
- id = form_params["id"]
- name = form_params["name"]
- nickname = form_params["nickname"]
- born = form_params["born"]
- email = form_params["email"]
- phone = form_params["phone"] |> format_phone
+ new_params = %{
+ id: id,
+ name: name,
+ nickname: nickname,
+ slug: friend.slug,
+ born: born,
+ phone: phone,
+ email: email
+ }
- 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)
- changeset = %Friend{}
- |> Friend.changeset(new_params)
- |> Map.put(:action, :validate)
-
- {
- :noreply, socket
- |> assign(:changeset, changeset)
- |> assign_friend(friend |> struct(new_params), changeset)
- }
+ {
+ :noreply,
+ socket
+ |> assign(:changeset, changeset)
+ |> assign_friend(friend |> struct(new_params), changeset)
+ }
end
# Handle form saving
- def handle_event("save", %{"friend" => form_params},%{assigns: %{changeset: changeset}} = socket) do
+ 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
+ id = form_params["id"]
- name = form_params["name"]
- nickname = form_params["nickname"]
- born = form_params["born"]
- email = form_params["email"]
- phone = form_params["phone"] |> format_phone
- id = form_params["id"]
+ new_params = %{
+ id: id,
+ name: name,
+ nickname: nickname,
+ slug: name |> to_slug,
+ born: born,
+ phone: phone,
+ email: email
+ }
- new_params = %{
- id: id,
- name: name,
- nickname: nickname,
- slug: name |> to_slug,
- born: born,
- phone: phone,
- email: email
- }
+ updated_friend = Friend.create_or_update(new_params)
+ new_changeset = updated_friend |> Friend.changeset()
- 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_patch(to: "/friend/#{updated_friend.slug}")
- }
+ {
+ :noreply,
+ socket
+ |> put_flash(:info, "Saved #{updated_friend |> first_name}!")
+ |> assign(:new_friend, new_changeset)
+ |> assign(:friend, updated_friend)
+ |> push_patch(to: "/friend/#{updated_friend.slug}")
+ }
end
# Handle deleting a friend
def handle_event("delete", %{"friend_id" => friend_id}, socket) do
-
friend = Friend.get_by_id(friend_id)
{:noreply,
- socket
- |> put_flash(:error, "Deleted '#{friend.name}'.")
- |> push_navigate(to: "/")
- }
-
- end
-
- # Set page title
- def title(socket, title) do
- socket |> assign(:page_title, title)
+ socket
+ |> put_flash(:error, "Deleted '#{friend.name}'.")
+ |> push_navigate(to: "/")}
end
# Set variables on page: friend, changeset, relationships
def assign_friend(socket, friend) do
socket
- |> assign(:friend, friend)
- |> assign(:changeset, friend |> Friend.changeset)
- |> assign(:relationships, friend.relationships)
+ |> assign(:friend, friend)
+ |> assign(:changeset, friend |> Friend.changeset())
+ |> assign(:relationships, friend.relationships)
end
# Same thing, but this time we have a changeset we want to keep
def assign_friend(socket, friend, changeset) do
socket
- |> assign(:friend, friend)
- |> assign(:changeset, changeset)
- |> assign(:relationships, friend.relationships)
- end
-
- # Set page_view variable
- def page_view(socket, page) do
- socket |> assign(:page_view, page)
+ |> assign(:friend, friend)
+ |> assign(:changeset, changeset)
+ |> assign(:relationships, friend.relationships)
end
# Route to the right sub-template in Components/Components.ex
def content(assigns) do
~H"""
<%= if @live_action != :new do %>
- <%= FriendsWeb.FriendLive.Friend.menu(assigns) %>
+ <%= FriendsWeb.FriendsLive.Friend.menu(assigns) %>
<% end %>
<%= cond do %>
<% @live_action == :show -> %>
@@ -177,7 +179,7 @@ defmodule FriendsWeb.FriendLive.Friend do
<%= for page <- ["overview", "calendar", "relationships"] do %>
<% is_active = if(page == @page_view) do "tab-active" end %>
- <.link patch={"/friend/#{@friend.slug}?page=#{page}"} class={"font-bold sm:tab-lg flex-grow no-underline tab tab-lifted #{is_active}"}>
+ <.link patch={"/friend/#{@friend.slug}/#{page}"} class={"font-bold sm:tab-lg flex-grow no-underline tab tab-lifted #{is_active}"}>
<%= page |> :string.titlecase() %>
<% end %>
@@ -185,5 +187,4 @@ defmodule FriendsWeb.FriendLive.Friend do
"""
end
-
end
diff --git a/friends/lib/friends_web/live/friend.html.heex b/friends/lib/friends_web/live/friend.html.heex
index 39e6945..12fe173 100644
--- a/friends/lib/friends_web/live/friend.html.heex
+++ b/friends/lib/friends_web/live/friend.html.heex
@@ -1,5 +1,5 @@
diff --git a/friends/lib/friends_web/live/show.ex b/friends/lib/friends_web/live/show.ex
index bff1446..c2fb39a 100644
--- a/friends/lib/friends_web/live/show.ex
+++ b/friends/lib/friends_web/live/show.ex
@@ -1,24 +1,31 @@
+"""
defmodule FriendsWeb.FriendLive.Show do
use FriendsWeb, :live_view
+ alias Friends.Friend
- import FriendsWeb.LiveView
-
- def mount(params, %{"user_token" => user_token}, socket) do
- {:ok,
- socket
- |> assign_current_user(user_token)
- }
+ def handle_params(attrs, token, socket) do
+ FriendsWeb.FriendLive.Friend.handle_params(attrs, token, socket)
end
- def mount(%{"slug" => slug}, _token, socket) do
- friend = slug |> Friends.Friend.get_by_slug
+ def mount(%{"slug" => slug} = attrs, token, socket) do
+ friend = slug |> Friends.Friend.get_by_slug()
+
+ page =
+ if (attrs |> Map.get("page")) in ["overview", "calendar", "relationships"] do
+ attrs["page"]
+ else
+ "overview"
+ end
+
{:ok,
socket
- |> assign_current_user(nil)
+ |> title(friend.name <> " - " <> (page |> :string.titlecase()))
+ |> page_view(page)
+ |> assign_current_user(token |> Map.get("user_token"))
|> assign(:friend, friend)
- }
+ |> assign(:changeset, %Friend{} |> Friend.changeset())
+ |> assign(:action, Routes.friend_path(socket, :update, friend.id))}
end
-
-
-
end
+
+"""
diff --git a/friends/lib/friends_web/live/show.html.heex b/friends/lib/friends_web/live/show.html.heex
index 9a102aa..39e6945 100644
--- a/friends/lib/friends_web/live/show.html.heex
+++ b/friends/lib/friends_web/live/show.html.heex
@@ -1 +1,5 @@
-
<%=@friend.name %>
\ No newline at end of file
+
diff --git a/friends/lib/friends_web/templates/friend/index.html.heex b/friends/lib/friends_web/templates/friend/index.html.heex
index 5083440..171a8b8 100644
--- a/friends/lib/friends_web/templates/friend/index.html.heex
+++ b/friends/lib/friends_web/templates/friend/index.html.heex
@@ -12,3 +12,8 @@
<% end %>
+<%= if @current_user do %>
+
+ <.link href="/friends/new" class="btn btn-primary">Add Friend
+
+<% end %>
\ No newline at end of file
diff --git a/friends/lib/friends_web/templates/profile_live/form.ex b/friends/lib/friends_web/templates/profile_live/form.ex
index a30e4d1..2a76eeb 100644
--- a/friends/lib/friends_web/templates/profile_live/form.ex
+++ b/friends/lib/friends_web/templates/profile_live/form.ex
@@ -1,6 +1,6 @@
defmodule FriendsWeb.ProfileLive.Form do
use FriendsWeb, :live_view
- import FriendsWeb.LiveView
+ import FriendsWeb.LiveHelpers
def mount(%{}, %{"user_token" => token}, socket) do
{:ok,
diff --git a/friends/lib/friends_web/views/live_helpers.ex b/friends/lib/friends_web/views/live_helpers.ex
new file mode 100644
index 0000000..c214372
--- /dev/null
+++ b/friends/lib/friends_web/views/live_helpers.ex
@@ -0,0 +1,33 @@
+defmodule FriendsWeb.LiveHelpers do
+ use FriendsWeb, :live_component
+
+ def assign_current_user(socket, user_token) do
+ user =
+ case user_token do
+ nil ->
+ nil
+
+ _moot ->
+ user_token
+ |> Friends.Accounts.get_user_by_session_token()
+ |> Friends.Repo.preload(:profile)
+ end
+
+ socket
+ |> assign(
+ :current_user,
+ user
+ )
+ end
+
+ # Set page title variable
+ def title(socket, title) do
+ socket
+ |> assign(:page_title, title)
+ end
+
+ # Set page_view variable
+ def page_view(socket, page) do
+ socket |> assign(:page_view, page)
+ end
+end
diff --git a/friends/lib/friends_web/views/live_view.ex b/friends/lib/friends_web/views/live_view.ex
deleted file mode 100644
index 8df2cde..0000000
--- a/friends/lib/friends_web/views/live_view.ex
+++ /dev/null
@@ -1,24 +0,0 @@
-defmodule FriendsWeb.LiveView do
- use FriendsWeb, :live_component
-
- def assign_current_user(socket, user_token) do
- user = case user_token do
- nil ->
- nil
- _moot ->
- user_token
- |> Friends.Accounts.get_user_by_session_token()
- |> Friends.Repo.preload(:profile)
- end
- socket
- |> assign(
- :current_user,
- user
- )
- end
-
- def title(socket, title) do
- socket
- |> assign(:page_title, title)
- end
-end