Validations, welcome flow bug fixes

This commit is contained in:
Ryan Pandya 2022-11-23 13:59:17 -05:00
parent afa816d2c2
commit 2f21ccd9de
5 changed files with 55 additions and 13 deletions

View File

@ -46,20 +46,35 @@ defmodule Friends.Friend do
:user_id, :user_id,
:address_id :address_id
]) ])
|> Ecto.Changeset.validate_required([:name, :email, :phone, :born]) |> Ecto.Changeset.validate_required([:name, :email, :phone, :born], message: "This field is required.")
|> Ecto.Changeset.validate_format(:name, ~r/\w+\ \w+/) |> Ecto.Changeset.validate_format(:name, ~r/\w+\ \w+/, message: "Please enter your full name.")
|> Ecto.Changeset.validate_format( |> Ecto.Changeset.validate_format(
:email, :email,
Regex.compile!("^[a-zA-Z0-9.!#$%&*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$") Regex.compile!("^[a-zA-Z0-9.!#$%&*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$"),
message: "Invalid email format."
) )
|> Ecto.Changeset.validate_format( |> Ecto.Changeset.validate_format(
:phone, :phone,
Regex.compile!("^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$") Regex.compile!("^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$"),
message: "Invalid phone format."
) )
|> validate_birthdate()
|> Ecto.Changeset.unique_constraint(:name) |> Ecto.Changeset.unique_constraint(:name)
|> Ecto.Changeset.unique_constraint(:email) |> Ecto.Changeset.unique_constraint(:email)
end end
defp validate_birthdate(%{changes: %{born: born}} = changeset) do
today = DateTime.utc_now |> DateTime.to_date
case born |> Date.diff(today) |> div(-365) do
age when age < 0 ->
changeset |> Ecto.Changeset.add_error(:born, "Please enter a date in the past.")
age when age > 90 ->
changeset |> Ecto.Changeset.add_error(:born, "Are you sure you're #{age} years old?")
_ -> changeset
end
end
defp validate_birthdate(changeset), do: changeset
def all() do def all() do
preloads = [:relationships, :reverse_relationships, :user, :address] preloads = [:relationships, :reverse_relationships, :user, :address]
@repo.all(from(f in Friends.Friend, preload: ^preloads)) @repo.all(from(f in Friends.Friend, preload: ^preloads))
@ -97,7 +112,7 @@ defmodule Friends.Friend do
|> load_preloads() |> load_preloads()
end end
def create(params) do def create(params \\ %{id: nil}) do
%Friend{} %Friend{}
|> Friend.changeset(%{params | id: nil}) |> Friend.changeset(%{params | id: nil})
|> Map.put(:action, :insert) |> Map.put(:action, :insert)
@ -223,7 +238,7 @@ defmodule Friends.Friend do
|> @repo.preload([:user, :relationships, :reverse_relationships, :address]) |> @repo.preload([:user, :relationships, :reverse_relationships, :address])
end end
def load_preloads(%Friends.Friend{} = friend), do: friend def load_preloads(friend), do: friend
def get_address(%Friend{} = friend) do def get_address(%Friend{} = friend) do
if friend.address do if friend.address do

View File

@ -185,7 +185,7 @@ defmodule FriendsWeb.FriendsLive.Components do
<li class="flex flex-row gap-x-6"> <li class="flex flex-row gap-x-6">
<strong class="md:text-xl w-20 md:w-28 shrink-0 text-right">Phone:</strong> <strong class="md:text-xl w-20 md:w-28 shrink-0 text-right">Phone:</strong>
<div class="flex flex-col h-16"> <div class="flex flex-col h-16">
<%= text_input f, :phone, class: "input input-primary input-sm md:input-md", phx_debounce: "blur", value: @friend.phone %> <%= text_input f, :phone, class: "input input-primary input-sm md:input-md", phx_debounce: "blur", value: @friend.phone |> FriendsWeb.LiveHelpers.display_phone(@changeset) %>
<div class="min-w-fit flex place-items-center mr-4"><%= error_tag f, :phone %></div> <div class="min-w-fit flex place-items-center mr-4"><%= error_tag f, :phone %></div>
</div> </div>
</li> </li>
@ -220,7 +220,7 @@ defmodule FriendsWeb.FriendsLive.Components do
<%= submit "Save", class: "btn btn-block btn-disabled" %> <%= submit "Save", class: "btn btn-block btn-disabled" %>
<% end %> <% end %>
</div> </div>
<%= if @current_user.profile.id == @friend.id do %> <%= if @live_action != :welcome and @current_user.profile.id == @friend.id do %>
<div class="flex-1"> <div class="flex-1">
<.link href={Routes.user_settings_path(FriendsWeb.Endpoint, :edit)} class="btn btn-block btn-error">Delete</.link> <.link href={Routes.user_settings_path(FriendsWeb.Endpoint, :edit)} class="btn btn-block btn-error">Delete</.link>
</div> </div>

View File

@ -17,6 +17,8 @@ defmodule FriendsWeb.FriendsLive.Edit do
|> assign(:live_action, live_action) |> assign(:live_action, live_action)
|> assign_current_user(token |> Map.get("user_token")) |> assign_current_user(token |> Map.get("user_token"))
|> assign(:friend, friend) |> assign(:friend, friend)
|> assign(:address_latlon, nil)
|> assign(:search_results, nil)
|> title("Welcome") |> title("Welcome")
|> assign(:changeset, %Friend{} |> Friend.changeset())} |> assign(:changeset, %Friend{} |> Friend.changeset())}
end end
@ -76,7 +78,7 @@ defmodule FriendsWeb.FriendsLive.Edit do
end end
def handle_event("validate", %{"friend" => form_params}, %{assigns: %{friend: friend}} = socket) do def handle_event("validate", %{"friend" => form_params}, %{assigns: %{friend: friend}} = socket) do
id = form_params["id"] |> String.to_integer() id = form_params["id"] |> parse_id
name = form_params["name"] name = form_params["name"]
nickname = form_params["nickname"] nickname = form_params["nickname"]
born = form_params["born"] born = form_params["born"]

View File

@ -10,10 +10,8 @@ defmodule FriendsWeb.ErrorHelpers do
""" """
def error_tag(form, field) do def error_tag(form, field) do
Enum.map(Keyword.get_values(form.errors, field), fn error -> Enum.map(Keyword.get_values(form.errors, field), fn error ->
content_tag(:span, translate_error(error), field = field |> Atom.to_string() |> String.capitalize()
class: "invalid-feedback", content_tag(:span, "#{translate_error(error)}", class: "block mt-1 text-sm text-red-700")
phx_feedback_for: input_name(form, field)
)
end) end)
end end

View File

@ -6,6 +6,33 @@ defmodule FriendsWeb.LiveHelpers do
atom |> to_string |> :string.titlecase() atom |> to_string |> :string.titlecase()
end end
def parse_id("new"), do: "new"
def parse_id(int), do: int |> String.to_integer()
def display_phone(phone, changeset) do
if changeset.errors[:phone] do
phone
else
display_phone(phone)
end
end
def display_phone(phone) do
"""
TODO: Actually implement this
"""
has_plus = phone |> String.starts_with?("+")
case phone |> String.length do
10 ->
country = "+1 "
[area, first, sec1, sec2] = phone |> to_charlist |> Enum.chunk_every(3) |> Enum.map(&(&1 |> to_string))
"#{country}(#{area}) #{first}-#{sec1}#{sec2}"
IO.inspect "#{country}(#{area}) #{first}-#{sec1}#{sec2}"
11 when has_plus ->
phone
end
end
def assign_current_user(socket, user_token) do def assign_current_user(socket, user_token) do
user = user =
case user_token do case user_token do