defmodule Rsh26poolWeb.ManageLive do @moduledoc """ The owner's management page: rename the room, end voting, and watch results (with vote counts) and participants update in real time. In grouping mode the computed teams are shown once voting has ended. """ use Rsh26poolWeb, :live_view alias Rsh26pool.JST alias Rsh26pool.Voting @impl true def mount(%{"room_number" => number}, _session, socket) do room = number |> Voting.get_room_by_number() |> Voting.ensure_closed() if connected?(socket), do: Voting.subscribe(room.id) {:ok, socket |> assign(:room, room) |> assign(:participant, socket.assigns.current_participant) |> assign(:page_title, "管理 - #{room.name}") |> assign(:name_form, to_form(Voting.change_room_settings(room))) |> load_state()} end @impl true def handle_event("rename", %{"room" => params}, socket) do case Voting.update_room_settings(socket.assigns.room, params) do {:ok, room} -> {:noreply, socket |> assign(:room, room) |> assign(:name_form, to_form(Voting.change_room_settings(room))) |> put_flash(:info, "ルーム名を変更しました。")} {:error, changeset} -> {:noreply, assign(socket, :name_form, to_form(changeset))} end end def handle_event("close", _params, socket) do {:ok, room} = Voting.close_room(socket.assigns.room) {:noreply, socket |> assign(:room, room) |> put_flash(:info, "投票を終了しました。") |> load_state()} end @impl true def handle_info({:voting, :room_updated}, socket) do room = socket.assigns.room.room_number |> Voting.get_room_by_number() |> Voting.ensure_closed() {:noreply, socket |> assign(:room, room) |> load_state()} end def handle_info({:voting, _event}, socket) do {:noreply, load_state(socket)} end ## State --------------------------------------------------------------- defp load_state(socket) do room = socket.assigns.room open? = Voting.room_open?(room) socket |> assign(:open?, open?) |> assign(:results, Voting.results(room)) |> assign(:participants, Voting.list_participants(room)) |> assign(:grouping, if(not open? and room.grouping_mode, do: Voting.group_assignments(room))) end ## Render -------------------------------------------------------------- @impl true def render(assigns) do ~H""" <.header> 管理ページ <:subtitle>{@room.name} <:actions> <.icon name="hero-hand-raised" class="size-4" /> 投票受付中 <.icon name="hero-lock-closed" class="size-4" /> 終了

参加者に伝えるルーム番号

{@room.room_number}

投票ページ:{url(~p"/vote/#{@room.room_number}")}

<.icon name="hero-clock" class="size-4" /> 自動終了予定:{JST.format(@room.closes_at)}(日本時間)

<.icon name="hero-pencil-square" class="size-5" /> ルーム名を変更

<.form for={@name_form} phx-submit="rename" id="rename-form" class="flex flex-col gap-2"> <.input field={@name_form[:name]} type="text" />

<.icon name="hero-lock-closed" class="size-5" /> 投票の終了

<%= if @open? do %>

投票を終了すると、参加者は投票できなくなります。 終了時にグループ分けが行われます。

<% else %>

この投票は終了しています。

<% end %>

<.icon name="hero-trophy" class="size-5 text-warning" /> 現在の結果 {length(@results)} 件

まだ投稿がありません。

  1. {index + 1}

    {result.idea.text}

    提案者:{result.idea.participant.name}

    <.icon name="hero-hand-thumb-up" class="size-4" /> {result.count}

<.icon name="hero-user-group" class="size-5 text-primary" /> グループ分けの結果

リーダーになる人が決まりませんでした(十分な票を集めた意見がありません)。

<.icon name="hero-user-group" class="size-5 text-primary" /> {group.leader.name} グループ

テーマ:{group.opinion && group.opinion.text}

  • <.icon name="hero-trophy" class="size-4 text-warning" /> {group.leader.name}(リーダー)
  • {member.name}

未割り当て:{Enum.map_join(@grouping.ungrouped, "、", & &1.name)}

<.icon name="hero-users" class="size-5" /> 参加者 {length(@participants)} 人

{p.name} (オーナー)
""" end end