From 138820e9ea0a2c4973960cf807b4b567cdee9ec9 Mon Sep 17 00:00:00 2001 From: Adrian Salamon Date: Sun, 24 Nov 2024 22:32:11 +0100 Subject: [PATCH 1/3] ability to close polls --- lib/haj/polls.ex | 16 ++++- lib/haj/polls/poll.ex | 3 +- lib/haj_web/live/poll_live/show.ex | 59 ++++++++++++++----- .../settings_live/polls/form_component.ex | 1 + .../20241124210659_add_poll_open_option.exs | 9 +++ 5 files changed, 69 insertions(+), 19 deletions(-) create mode 100644 priv/repo/migrations/20241124210659_add_poll_open_option.exs diff --git a/lib/haj/polls.ex b/lib/haj/polls.ex index 4a4097e..d5c75e7 100644 --- a/lib/haj/polls.ex +++ b/lib/haj/polls.ex @@ -70,9 +70,13 @@ defmodule Haj.Polls do """ def update_poll(%Poll{} = poll, attrs) do - poll - |> Poll.changeset(attrs) - |> Repo.update() + res = + poll + |> Poll.changeset(attrs) + |> Repo.update() + + broadcast_updated_poll(res) + res end @doc """ @@ -410,4 +414,10 @@ defmodule Haj.Polls do defp broadcast(poll_id, event, payload) do PubSub.broadcast(Haj.PubSub, "poll:#{poll_id}", {event, payload}) end + + defp broadcast_updated_poll({:ok, poll}) do + PubSub.broadcast(Haj.PubSub, "poll:#{poll.id}", {:poll_updated, %{poll: poll}}) + end + + defp broadcast_updated_poll({:error, _changeset}), do: :ok end diff --git a/lib/haj/polls/poll.ex b/lib/haj/polls/poll.ex index eec3aae..c44eed4 100644 --- a/lib/haj/polls/poll.ex +++ b/lib/haj/polls/poll.ex @@ -7,6 +7,7 @@ defmodule Haj.Polls.Poll do field :title, :string field :display_votes, :boolean, default: false field :allow_user_options, :boolean, default: false + field :open, :boolean, default: true has_many :options, Haj.Polls.Option has_many :votes, Haj.Polls.Vote @@ -17,7 +18,7 @@ defmodule Haj.Polls.Poll do @doc false def changeset(poll, attrs) do poll - |> cast(attrs, [:title, :description, :display_votes, :allow_user_options]) + |> cast(attrs, [:title, :description, :display_votes, :allow_user_options, :open]) |> validate_required([:title, :description, :display_votes, :allow_user_options]) end end diff --git a/lib/haj_web/live/poll_live/show.ex b/lib/haj_web/live/poll_live/show.ex index 281f15d..03adedb 100644 --- a/lib/haj_web/live/poll_live/show.ex +++ b/lib/haj_web/live/poll_live/show.ex @@ -9,21 +9,27 @@ defmodule HajWeb.PollLive.Show do @impl true def mount(%{"id" => id}, _session, socket) do poll = Polls.get_poll!(id) - options = Polls.list_options_for_poll(id) - user_votes = Polls.list_user_votes_for_poll(id, socket.assigns.current_user.id) + {options, user_votes} = get_options(id, socket.assigns.current_user.id) if connected?(socket) do Polls.subscribe(id) end + {:ok, + assign(socket, poll: poll, user_votes: user_votes) + |> stream(:options, options)} + end + + defp get_options(poll_id, user_id) do + options = Polls.list_options_for_poll(poll_id) + user_votes = Polls.list_user_votes_for_poll(poll_id, user_id) + options = Enum.map(options, fn option -> Map.put(option, :voted, Enum.any?(user_votes, fn vote -> vote.option_id == option.id end)) end) - {:ok, - assign(socket, poll: poll, user_votes: user_votes) - |> stream(:options, options)} + {options, user_votes} end @impl true @@ -38,12 +44,18 @@ defmodule HajWeb.PollLive.Show do end defp apply_action(socket, :new_option, _params) do - socket - |> assign(:page_title, "Nytt alternativ") - |> assign(:option, %Option{ - poll_id: socket.assigns.poll.id, - creator_id: socket.assigns.current_user.id - }) + if socket.assigns.poll.open do + socket + |> assign(:page_title, "Nytt alternativ") + |> assign(:option, %Option{ + poll_id: socket.assigns.poll.id, + creator_id: socket.assigns.current_user.id + }) + else + socket + |> put_flash(:error, "Röstningen är stängd") + |> push_patch(to: ~p"/polls/#{socket.assigns.poll}") + end end @impl true @@ -88,10 +100,21 @@ defmodule HajWeb.PollLive.Show do |> stream_insert(:options, option, at: pos - 1)} end + @impl true + def handle_info({:poll_updated, %{poll: poll}}, socket) do + {options, user_votes} = get_options(poll.id, socket.assigns.current_user.id) + + {:noreply, assign(socket, poll: poll, user_votes: user_votes) |> stream(:options, options)} + end + @impl true def handle_event("vote", %{"id" => id}, socket) do - {:ok, _} = Polls.toggle_user_vote_for_option(id, socket.assigns.current_user.id) - {:noreply, socket} + if socket.assigns.poll.open do + {:ok, _} = Polls.toggle_user_vote_for_option(id, socket.assigns.current_user.id) + {:noreply, socket} + else + {:noreply, put_flash(socket, :error, "Röstningen är stängd")} + end end @impl true @@ -101,7 +124,12 @@ defmodule HajWeb.PollLive.Show do
<%= @poll.title %> - <%= @poll.description %> + + <%= @poll.description %> + + Röstningen är stängd + +
@@ -115,7 +143,7 @@ defmodule HajWeb.PollLive.Show do role="list" phx-update="stream" id="options" - class="mt-4 divide divide-gray-100 grid grid-cols-2 gap-x-4" + class="divide mt-4 grid grid-cols-2 gap-x-4 divide-gray-100" >
diff --git a/lib/haj_web/live/settings_live/polls/form_component.ex b/lib/haj_web/live/settings_live/polls/form_component.ex index 3cfe7e8..b2218c4 100644 --- a/lib/haj_web/live/settings_live/polls/form_component.ex +++ b/lib/haj_web/live/settings_live/polls/form_component.ex @@ -21,6 +21,7 @@ defmodule HajWeb.PollLive.FormComponent do > <.input field={@form[:title]} type="text" label="Title" /> <.input field={@form[:description]} type="text" label="Description" /> + <.input field={@form[:open]} type="checkbox" label="Open for voting" /> <.input field={@form[:display_votes]} type="checkbox" label="Display votes" /> <.input field={@form[:allow_user_options]} type="checkbox" label="Allow user options" /> <:actions> diff --git a/priv/repo/migrations/20241124210659_add_poll_open_option.exs b/priv/repo/migrations/20241124210659_add_poll_open_option.exs new file mode 100644 index 0000000..0e7a3a5 --- /dev/null +++ b/priv/repo/migrations/20241124210659_add_poll_open_option.exs @@ -0,0 +1,9 @@ +defmodule Haj.Repo.Migrations.AddPollOpenOption do + use Ecto.Migration + + def change do + alter table(:polls) do + add :open, :boolean, default: true + end + end +end From 8ea6d085fa309ab8a7718b0b4312d39e150a2d51 Mon Sep 17 00:00:00 2001 From: Adrian Salamon Date: Sun, 24 Nov 2024 22:33:30 +0100 Subject: [PATCH 2/3] think about the poor mobile users --- lib/haj_web/live/poll_live/show.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/haj_web/live/poll_live/show.ex b/lib/haj_web/live/poll_live/show.ex index 03adedb..9a30421 100644 --- a/lib/haj_web/live/poll_live/show.ex +++ b/lib/haj_web/live/poll_live/show.ex @@ -143,7 +143,7 @@ defmodule HajWeb.PollLive.Show do role="list" phx-update="stream" id="options" - class="divide mt-4 grid grid-cols-2 gap-x-4 divide-gray-100" + class="divide mt-4 grid gap-x-4 divide-gray-100 md:grid-cols-2" >
Date: Sun, 24 Nov 2024 22:47:17 +0100 Subject: [PATCH 3/3] no voting = no buttons --- lib/haj_web/live/poll_live/show.ex | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/lib/haj_web/live/poll_live/show.ex b/lib/haj_web/live/poll_live/show.ex index 9a30421..923d855 100644 --- a/lib/haj_web/live/poll_live/show.ex +++ b/lib/haj_web/live/poll_live/show.ex @@ -148,19 +148,19 @@ defmodule HajWeb.PollLive.Show do
@@ -188,10 +188,7 @@ defmodule HajWeb.PollLive.Show do
-

+

<%= option.description %>