defmodule PainWeb.Components.Schedule do use Surface.LiveComponent import Pain.Schedule prop service_keys, :list, default: [] prop employee_keys, :list, default: [] prop schedule, :event, required: true data possible, :map, default: %{} data day, :string data block, :string, default: nil data process, :reference, default: nil def mount(socket), do: {:ok, socket |> assign(:day, today() |> Date.to_string) } def update(assigns, socket) do {:ok, socket |> assign(assigns |> Map.take(~w[ service_keys employee_keys schedule day block process ]a)) |> assign( if assigns[:possible], do: %{ possible: Map.merge(socket.assigns[:possible], assigns[:possible]) }, else: %{ process: Task.async(fn -> service_demand(assigns[:service_keys]) |> check_blocks(assigns[:employee_keys], this_month()) |> blocks_by_day() end) } ) |> push_event("color", %{}) } end def handle_event("schedule_day", params, socket) do {:noreply, socket |> assign(:day, params["day"]) |> assign( if socket.assigns[:possible][params["day"]], do: %{}, else: %{ process: Task.async(fn -> service_demand(socket.assigns[:service_keys]) |> check_blocks(socket.assigns[:employee_keys], range(day(params["day"]))) |> blocks_by_day() end) }) } end def handle_event("schedule_month", params, socket) do {:noreply, socket |> assign(:process, Task.async(fn -> service_demand(socket.assigns[:service_keys]) |> check_blocks( socket.assigns[:employee_keys], month("#{params["year"]}-#{params["month"]}") ) |> blocks_by_day() end)) } end def render(assigns) do ~F"""
Enum.map(fn {d,b} -> {d, length b } end) |> Enum.into(%{}) |> Jason.encode! } >
{#if @process}...loading... {#elseif length(@possible[@day] || []) == 0} There are no more openings on {@day}. {#else} Please choose a block of time on {@day}.
{#for {hour, mins} <- (@possible[@day] |> hour_map())}
{hour}: {#for min <- mins}
{min}
{/for}
{/for}
{/if}
""" end end