From 2a1d990ad00c12d052252b09a3564fe07000bb85 Mon Sep 17 00:00:00 2001 From: Alex Lion Date: Fri, 13 Feb 2026 18:42:09 +0100 Subject: [PATCH] Improve interaction and attendees submissions panes --- lib/claper_web/live/event_live/manage.ex | 8 + .../live/event_live/manage.html.heex | 317 +----------------- .../manage_audience_responses_component.ex | 301 +++++++++++++++++ .../manage_interaction_list_component.ex | 280 ++++++++-------- .../event_live/manageable_post_component.ex | 287 ++++++++-------- 5 files changed, 610 insertions(+), 583 deletions(-) create mode 100644 lib/claper_web/live/event_live/manage_audience_responses_component.ex diff --git a/lib/claper_web/live/event_live/manage.ex b/lib/claper_web/live/event_live/manage.ex index e5c3b80..2b24c36 100644 --- a/lib/claper_web/live/event_live/manage.ex +++ b/lib/claper_web/live/event_live/manage.ex @@ -814,6 +814,8 @@ defmodule ClaperWeb.EventLive.Manage do defp apply_action(socket, :add_poll, _params) do socket |> assign(:create, "poll") + |> assign(:interaction_modal, true) + |> assign(:create_action, :new) |> assign(:poll, %Polls.Poll{ poll_opts: [%Polls.PollOpt{content: gettext("Yes")}, %Polls.PollOpt{content: gettext("No")}] }) @@ -832,6 +834,8 @@ defmodule ClaperWeb.EventLive.Manage do defp apply_action(socket, :add_form, _params) do socket |> assign(:create, "form") + |> assign(:interaction_modal, true) + |> assign(:create_action, :new) |> assign(:form, %Forms.Form{ fields: [ %Forms.Field{name: gettext("Name"), type: "text"}, @@ -843,6 +847,8 @@ defmodule ClaperWeb.EventLive.Manage do defp apply_action(socket, :add_embed, _params) do socket |> assign(:create, "embed") + |> assign(:interaction_modal, true) + |> assign(:create_action, :new) |> assign(:embed, %Embeds.Embed{}) end @@ -875,6 +881,8 @@ defmodule ClaperWeb.EventLive.Manage do defp apply_action(socket, :add_quiz, _params) do socket |> assign(:create, "quiz") + |> assign(:interaction_modal, true) + |> assign(:create_action, :new) |> assign(:quiz, %Quizzes.Quiz{ presentation_file_id: socket.assigns.event.presentation_file.id, quiz_questions: [ diff --git a/lib/claper_web/live/event_live/manage.html.heex b/lib/claper_web/live/event_live/manage.html.heex index 624508d..ee08fd3 100644 --- a/lib/claper_web/live/event_live/manage.html.heex +++ b/lib/claper_web/live/event_live/manage.html.heex @@ -549,7 +549,7 @@
0} - class="flex-shrink-0 h-1/3" + class="flex-shrink-0 h-2/5" > <.live_component id="slide-preview" @@ -564,7 +564,7 @@
#{gettext("This section contains all your interactions for the current slide.")}

"} @@ -578,314 +578,23 @@ />
- +
#{gettext("Here you'll find all interactions from your attendees.")}

"} data-tg-group="manage" > -
-
-
- - - - {gettext("Options")} -
- -
- - - - -
- <%= if @list_tab == :posts do %> -
- - - -

{gettext("Messages from attendees will appear here.")}

-
-
0} - id="post-list" - class="p-4 space-y-3" - phx-update="stream" - phx-hook="ScrollIntoDiv" - > - <.live_component - :for={{id, post} <- @streams.posts} - module={ClaperWeb.EventLive.ManageablePostComponent} - id={id} - event={@event} - post={post} - /> -
- <% end %> - - <%= if @list_tab == :questions do %> -
- - - -

{gettext("Questions will appear here.")}

-
-
0} class="flex flex-col h-full"> -
- - -
-
- <.live_component - :for={{id, post} <- @streams.questions} - module={ClaperWeb.EventLive.ManageablePostComponent} - id={id} - event={@event} - post={post} - /> -
-
- <% end %> - - <%= if @list_tab == :pinned_posts do %> -
- - - -

{gettext("Pinned messages will appear here.")}

-
-
0} - id="pinned-post-list" - class="p-4 space-y-3" - phx-update="stream" - phx-hook="ScrollIntoDiv" - > - <.live_component - :for={{id, post} <- @streams.pinned_posts} - module={ClaperWeb.EventLive.ManageablePostComponent} - id={id} - event={@event} - post={post} - /> -
- <% end %> - - <%= if @list_tab == :forms do %> -
- - - - - - - - - -

{gettext("Form submissions will appear here.")}

-
-
-
-
-
- - {submission.form.title} - - -
-
- <%= if submission.attendee_identifier do %> - - <% else %> - - <% end %> -
- <%= for res <- submission.response do %> -

- {elem(res, 0)}: - {elem(res, 1)} -

- <% end %> -
-
-
-
-
- <% end %> -
-
+
diff --git a/lib/claper_web/live/event_live/manage_audience_responses_component.ex b/lib/claper_web/live/event_live/manage_audience_responses_component.ex new file mode 100644 index 0000000..bca24a9 --- /dev/null +++ b/lib/claper_web/live/event_live/manage_audience_responses_component.ex @@ -0,0 +1,301 @@ +defmodule ClaperWeb.EventLive.ManageAudienceResponsesComponent do + @moduledoc false + use Phoenix.Component + use Gettext, backend: ClaperWeb.Gettext + + def render(assigns) do + ~H""" +
+
+ + + + {gettext("Audience Responses")} +
+ + + + + +
+ <%= if @list_tab == :posts do %> +
+ + + +

{gettext("Messages from attendees will appear here.")}

+
+
0} + id="post-list" + class="p-2 space-y-3" + phx-update="stream" + phx-hook="ScrollIntoDiv" + > + <.live_component + :for={{id, post} <- @streams.posts} + module={ClaperWeb.EventLive.ManageablePostComponent} + id={id} + event={@event} + post={post} + /> +
+ <% end %> + + <%= if @list_tab == :questions do %> +
+ + + +

{gettext("Questions will appear here.")}

+
+
0} class="flex flex-col h-full"> +
+ + +
+
+ <.live_component + :for={{id, post} <- @streams.questions} + module={ClaperWeb.EventLive.ManageablePostComponent} + id={id} + event={@event} + post={post} + /> +
+
+ <% end %> + + <%= if @list_tab == :pinned_posts do %> +
+ + + +

{gettext("Pinned messages will appear here.")}

+
+
0} + id="pinned-post-list" + class="p-2 space-y-3" + phx-update="stream" + phx-hook="ScrollIntoDiv" + > + <.live_component + :for={{id, post} <- @streams.pinned_posts} + module={ClaperWeb.EventLive.ManageablePostComponent} + id={id} + event={@event} + post={post} + /> +
+ <% end %> + + <%= if @list_tab == :forms do %> +
+ + + + + + + + + +

{gettext("Form submissions will appear here.")}

+
+
+
+
+
+ + {submission.form.title} + + +
+
+ <%= if submission.attendee_identifier do %> + + <% else %> + + <% end %> +
+ <%= for res <- submission.response do %> +

+ {elem(res, 0)}: + {elem(res, 1)} +

+ <% end %> +
+
+
+
+
+ <% end %> +
+
+ """ + end +end diff --git a/lib/claper_web/live/event_live/manage_interaction_list_component.ex b/lib/claper_web/live/event_live/manage_interaction_list_component.ex index 6aa5291..7c6eba3 100644 --- a/lib/claper_web/live/event_live/manage_interaction_list_component.ex +++ b/lib/claper_web/live/event_live/manage_interaction_list_component.ex @@ -3,143 +3,72 @@ defmodule ClaperWeb.EventLive.ManageInteractionListComponent do def render(assigns) do ~H""" -
-
+
+
+ + - {gettext("Interactions")} + {gettext("Interactions")}
-
-
- - - -

- {gettext("No interactions on this slide")} -

-
- <%= for interaction <- @interactions do %> -
-
- <%= case interaction do %> - <% %Claper.Polls.Poll{} -> %> -
- - - -
-
-

{gettext("Poll")}

-

{interaction.title}

-
- <% %Claper.Forms.Form{} -> %> -
- - - -
-
-

{gettext("Form")}

-

{interaction.title}

-
- <% %Claper.Embeds.Embed{} -> %> -
- - - -
-
-

{gettext("Web content")}

-

{interaction.title}

-
- <% %Claper.Quizzes.Quiz{} -> %> -
- - - -
-
-

{gettext("Quiz")}

-

{interaction.title}

-
- <% _ -> %> - <% end %> -
-
- <.link - patch={edit_path(@event_code, interaction)} - class="p-1.5 rounded-md hover:bg-gray-100 text-gray-500 hover:text-gray-700 transition-colors" - > +
+ + + +

+ {gettext("No interactions on this slide")} +

+
+ + <%= for interaction <- @interactions do %> +
+
+ <%= case interaction do %> + <% %Claper.Polls.Poll{} -> %> - - -
+ <% %Claper.Forms.Form{} -> %> + + + + <% %Claper.Embeds.Embed{} -> %> + + + + <% %Claper.Quizzes.Quiz{} -> %> + + + + <% _ -> %> + <% end %>
- <% end %> -
+ +
+

+ {interaction.title} +

+

+ {type_label(interaction)} +

+
+ + <.link + patch={edit_path(@event_code, interaction)} + class="flex items-center justify-center rounded-full w-[42px] h-[41px] shrink-0 border border-[#140553] text-[#140553]" + > + + + + + + +
+ <% end %>
""" end + defp type_label(%Claper.Polls.Poll{}), do: gettext("Poll") + defp type_label(%Claper.Forms.Form{}), do: gettext("Form") + defp type_label(%Claper.Embeds.Embed{}), do: gettext("Web content") + defp type_label(%Claper.Quizzes.Quiz{}), do: gettext("Quiz") + defp type_label(_), do: "" + defp edit_path(event_code, %Claper.Polls.Poll{id: id}), do: ~p"/e/#{event_code}/manage/edit/poll/#{id}" diff --git a/lib/claper_web/live/event_live/manageable_post_component.ex b/lib/claper_web/live/event_live/manageable_post_component.ex index 68ba5b5..75533f9 100644 --- a/lib/claper_web/live/event_live/manageable_post_component.ex +++ b/lib/claper_web/live/event_live/manageable_post_component.ex @@ -5,153 +5,158 @@ defmodule ClaperWeb.EventLive.ManageablePostComponent do assigns = assigns |> assign_new(:readonly, fn -> false end) ~H""" -
-
- - - - - {gettext("Question")} -
-
- <%= if @post.attendee_identifier do %> - - {link( - if @post.pinned do - gettext("Unpin") - else - gettext("Pin") - end, - to: "#", - phx_click: "pin", - phx_value_id: @post.uuid, - phx_value_event_id: @event.uuid - )} - - / - - {link(gettext("Ban"), - to: "#", - phx_click: "ban", - phx_value_attendee_identifier: @post.attendee_identifier, - data: [ - confirm: - gettext( - "Blocking this user will delete all his messages and he will not be able to join again, confirm ?" - ) - ] - )} - - / - <% else %> - - {link( - if @post.pinned do - gettext("Unpin") - else - gettext("Pin") - end, - to: "#", - phx_click: "pin", - phx_value_id: @post.uuid, - phx_value_event_id: @event.uuid - )} - - / - - {link(gettext("Ban"), - to: "#", - phx_click: "ban", - phx_value_user_id: @post.user_id, - data: [ - confirm: - gettext( - "Blocking this user will delete all his messages and he will not be able to join again, confirm ?" - ) - ] - )} - - / - <% end %> - - {link(gettext("Delete"), - to: "#", - phx_click: "delete", - phx_value_id: @post.uuid, - phx_value_event_id: @event.uuid - )} +
+ +
+ + {Calendar.strftime(@post.inserted_at, "%H:%M")} +
+
+ <%= if @post.name do %> + {String.first(@post.name)} + <% end %> +
+
-
- <%= if @post.attendee_identifier do %> - - <% else %> - - <% end %> - -
- <%= if @post.name do %> -

- {@post.name} -

- <% end %> - -

- {ClaperWeb.Helpers.format_body(@post.body)} + +

+ +
+

+ {@post.name}

+
+ + + + {gettext("Question")} +
+ + +
+ + <%= if @post.attendee_identifier do %> + + <% else %> + + <% end %> + +
+
+ + +
+ + + +
+

+ {ClaperWeb.Helpers.format_body(@post.body)} +

+ + <%= if @post.like_count > 0 || @post.love_count > 0 || @post.lol_count > 0 do %> +
+
0} + class="border border-gray-200 rounded-full px-2 py-2 flex items-center gap-1" + > + 👍 + {@post.like_count} +
+
0} + class="border border-gray-200 rounded-full px-2 py-2 flex items-center gap-1" + > + ❤️ + {@post.love_count} +
+
0} + class="border border-gray-200 rounded-full px-2 py-2 flex items-center gap-1" + > + 😂 + {@post.lol_count} +
+
+ <% end %> +
- - <%= if @post.like_count> 0 || @post.love_count > 0 || @post.lol_count > 0 do %> -
-
- <%= if @post.like_count> 0 do %> - - - {@post.like_count} - - <% end %> -
-
- <%= if @post.love_count> 0 do %> - - - {@post.love_count} - - <% end %> -
-
- <%= if @post.lol_count> 0 do %> - - - {@post.lol_count} - - <% end %> -
-
- <% end %>
""" end