defmodule LocalspotWeb.BusinessLive.New do
use LocalspotWeb, :live_view
alias Localspot.Businesses
alias Localspot.Businesses.Business
@impl true
def mount(_params, _session, socket) do
categories = Businesses.list_categories()
changeset = Businesses.change_business(%Business{})
{:ok,
socket
|> assign(:page_title, "Add Your Business")
|> assign(:categories, categories)
|> assign(:form, to_form(changeset))
|> assign(:hours, default_hours())
|> assign(:photo_url, "")}
end
@impl true
def handle_event("validate", %{"business" => business_params}, socket) do
changeset =
%Business{}
|> Businesses.change_business(business_params)
|> Map.put(:action, :validate)
{:noreply, assign(socket, :form, to_form(changeset))}
end
@impl true
def handle_event("update_hours", %{"day" => day, "field" => field, "value" => value}, socket) do
day = String.to_integer(day)
hours = update_hours(socket.assigns.hours, day, field, value)
{:noreply, assign(socket, :hours, hours)}
end
@impl true
def handle_event("update_photo_url", %{"value" => value}, socket) do
{:noreply, assign(socket, :photo_url, value)}
end
@impl true
def handle_event("save", %{"business" => business_params}, socket) do
business_params =
business_params
|> Map.put("slug", Businesses.generate_slug(business_params["name"] || ""))
|> Map.put("locally_owned", true)
hours_attrs = build_hours_attrs(socket.assigns.hours)
photo_attrs = build_photo_attrs(socket.assigns.photo_url)
case Businesses.create_business_with_associations(business_params, hours_attrs, photo_attrs) do
{:ok, business} ->
{:noreply,
socket
|> put_flash(:info, "Business submitted successfully!")
|> push_navigate(to: ~p"/businesses/#{business.slug}")}
{:error, %Ecto.Changeset{} = changeset} ->
{:noreply, assign(socket, :form, to_form(changeset))}
end
end
defp default_hours do
for day <- 0..6, into: %{} do
{day, %{closed: day == 0, opens_at: "09:00", closes_at: "17:00"}}
end
end
defp update_hours(hours, day, "closed", value) do
put_in(hours, [day, :closed], value == "true")
end
defp update_hours(hours, day, field, value) do
put_in(hours, [day, String.to_existing_atom(field)], value)
end
defp build_hours_attrs(hours) do
hours
|> Enum.map(fn {day, data} ->
if data.closed do
%{day_of_week: day, closed: true}
else
%{
day_of_week: day,
closed: false,
opens_at: parse_time(data.opens_at),
closes_at: parse_time(data.closes_at)
}
end
end)
end
defp parse_time(time_string) do
case Time.from_iso8601(time_string <> ":00") do
{:ok, time} -> time
_ -> nil
end
end
defp build_photo_attrs(""), do: []
defp build_photo_attrs(url), do: [%{url: url, primary: true}]
@impl true
def render(assigns) do
~H"""
Coordinates help customers find you on the map. You can find yours on Google Maps.
Enter a URL to an image of your business. Direct image links work best.
Basic Information
<.input field={@form[:name]} label="Business Name" required />
<.input field={@form[:description]} type="textarea" label="Description" rows="3" />
Location
<.input field={@form[:street_address]} label="Street Address" required />
Contact Information
<.input field={@form[:phone]} label="Phone Number" placeholder="6145551234" />
<.input field={@form[:email]} type="email" label="Email Address" />
<.input
field={@form[:website]}
type="url"
label="Website"
placeholder="https://example.com"
/>
Business Hours
Photo
Local Ownership Attestation