Skip to content

Commit

Permalink
feat: ineligible attendees (#511)
Browse files Browse the repository at this point in the history
Co-authored-by: Rui Oliveira <[email protected]>
  • Loading branch information
joaodiaslobo and ruioliveira02 authored Feb 11, 2025
1 parent 128ea0f commit 12356a2
Show file tree
Hide file tree
Showing 13 changed files with 221 additions and 47 deletions.
3 changes: 2 additions & 1 deletion lib/safira/accounts/attendee.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ defmodule Safira.Accounts.Attendee do
use Safira.Schema

@required_fields ~w(user_id)a
@optional_fields ~w(tokens entries course_id)a
@optional_fields ~w(tokens entries course_id ineligible)a

schema "attendees" do
field :tokens, :integer, default: 0
field :entries, :integer, default: 0
field :cv, Uploaders.CV.Type
field :ineligible, :boolean, default: false

belongs_to :course, Safira.Accounts.Course
belongs_to :user, Safira.Accounts.User
Expand Down
1 change: 1 addition & 0 deletions lib/safira/contest.ex
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,7 @@ defmodule Safira.Contest do
query
|> join(:inner, [dt, rd], at in Safira.Accounts.Attendee, on: at.id == rd.attendee_id)
|> join(:inner, [dt, rd, at], u in Safira.Accounts.User, on: u.id == at.user_id)
|> where([dt, rd, at, u], not at.ineligible)
|> select([dt, rd, at, u], %{
attendee_id: at.id,
position:
Expand Down
2 changes: 1 addition & 1 deletion lib/safira_web.ex
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ defmodule SafiraWeb do
those modules here.
"""

def static_paths, do: ~w(assets docs fonts images models favicon.ico robots.txt)
def static_paths, do: ~w(assets docs fonts images models favicon.ico robots.txt 30anos.html)

def router do
quote do
Expand Down
2 changes: 1 addition & 1 deletion lib/safira_web/components/layouts/app.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<.sidebar
:if={Map.get(assigns, :event_started, true)}
current_user={@current_user}
pages={SafiraWeb.Config.app_pages()}
pages={SafiraWeb.Config.app_pages(!@current_user.attendee.ineligible)}
current_page={Map.get(assigns, :current_page, nil)}
background="bg-primary"
border="border-darkShade"
Expand Down
27 changes: 18 additions & 9 deletions lib/safira_web/config.ex
Original file line number Diff line number Diff line change
Expand Up @@ -43,58 +43,67 @@ defmodule SafiraWeb.Config do
|> Enum.filter(fn x -> Enum.member?(enabled_flags, x.feature_flag) end)
end

def app_pages do
def app_pages(attendee_eligible?) do
if Event.event_started?() do
[
%{
key: :badges,
title: "Badgedex",
icon: "hero-check-badge",
url: "/app/badges"
url: "/app/badges",
enabled: true
},
%{
key: :wheel,
title: "Wheel",
icon: "hero-circle-stack",
url: "/app/wheel"
url: "/app/wheel",
enabled: attendee_eligible?
},
%{
key: :coin_flip,
title: "Coin Flip",
icon: "hero-circle-stack",
url: "/app/coin_flip"
url: "/app/coin_flip",
enabled: attendee_eligible?
},
%{
key: :slots,
title: "Slots",
icon: "hero-circle-stack",
url: "/app/slots"
url: "/app/slots",
enabled: true
},
%{
key: :leaderboard,
title: "Leaderboard",
icon: "hero-trophy",
url: "/app/leaderboard"
url: "/app/leaderboard",
enabled: true
},
%{
key: :store,
title: "Store",
icon: "hero-shopping-bag",
url: "/app/store"
url: "/app/store",
enabled: true
},
%{
key: :vault,
title: "Vault",
icon: "hero-archive-box",
url: "/app/vault"
url: "/app/vault",
enabled: true
},
%{
key: :credential,
title: "Credential",
icon: "hero-qr-code",
url: "/app/credential"
url: "/app/credential",
enabled: true
}
]
|> Enum.filter(& &1.enabled)
else
[]
end
Expand Down
2 changes: 1 addition & 1 deletion lib/safira_web/controllers/download_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ defmodule SafiraWeb.DownloadController do
end

defp final_draw_lines(user) do
if user.attendee.entries < 10 do
if user.attendee.entries < 10 and !user.attendee.ineligible do
[]
else
for _ <- 1..user.attendee.entries do
Expand Down
45 changes: 26 additions & 19 deletions lib/safira_web/live/app/coin_flip_live/index.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,35 @@ defmodule SafiraWeb.App.CoinFlipLive.Index do

@impl true
def mount(_params, _session, socket) do
if connected?(socket) do
Minigames.subscribe_to_coin_flip_config_update("fee")
Minigames.subscribe_to_coin_flip_config_update("is_active")
Minigames.subscribe_to_coin_flip_rooms_update()
end
if socket.assigns.current_user.attendee.ineligible do
{:ok,
socket
|> put_flash(:error, "Can't play the coin flip minigame with this account.")
|> push_navigate(to: ~p"/app")}
else
if connected?(socket) do
Minigames.subscribe_to_coin_flip_config_update("fee")
Minigames.subscribe_to_coin_flip_config_update("is_active")
Minigames.subscribe_to_coin_flip_rooms_update()
end

room_list = Minigames.list_current_coin_flip_rooms()
room_list = Minigames.list_current_coin_flip_rooms()

previous_room_list = Minigames.list_previous_coin_flip_rooms(4)
previous_room_list = Minigames.list_previous_coin_flip_rooms(4)

{:ok,
socket
|> assign(:current_page, :coin_flip)
|> assign(:attendee_tokens, socket.assigns.current_user.attendee.tokens)
|> assign(:coin_flip_fee, Minigames.get_coin_flip_fee())
|> assign(:result, nil)
|> assign(:coin_flip_active?, Minigames.coin_flip_active?())
|> assign(:bet, 10)
|> stream(:room_list, room_list)
|> assign(:room_list_count, room_list |> Enum.count())
|> stream(:previous_room_list, previous_room_list)
|> assign(:previous_room_list_count, previous_room_list |> Enum.count())}
{:ok,
socket
|> assign(:current_page, :coin_flip)
|> assign(:attendee_tokens, socket.assigns.current_user.attendee.tokens)
|> assign(:coin_flip_fee, Minigames.get_coin_flip_fee())
|> assign(:result, nil)
|> assign(:coin_flip_active?, Minigames.coin_flip_active?())
|> assign(:bet, 10)
|> stream(:room_list, room_list)
|> assign(:room_list_count, room_list |> Enum.count())
|> stream(:previous_room_list, previous_room_list)
|> assign(:previous_room_list_count, previous_room_list |> Enum.count())}
end
end

def handle_event("create-room", _params, socket) do
Expand Down
31 changes: 19 additions & 12 deletions lib/safira_web/live/app/wheel_live/index.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,26 @@ defmodule SafiraWeb.App.WheelLive.Index do

@impl true
def mount(_params, _session, socket) do
if connected?(socket) do
Minigames.subscribe_to_wheel_config_update("price")
Minigames.subscribe_to_wheel_config_update("is_active")
end
if socket.assigns.current_user.attendee.ineligible do
{:ok,
socket
|> put_flash(:error, "Can't play the wheel minigame with this account.")
|> push_navigate(to: ~p"/app")}
else
if connected?(socket) do
Minigames.subscribe_to_wheel_config_update("price")
Minigames.subscribe_to_wheel_config_update("is_active")
end

{:ok,
socket
|> assign(:current_page, :wheel)
|> assign(:in_spin?, false)
|> assign(:attendee_tokens, socket.assigns.current_user.attendee.tokens)
|> assign(:wheel_price, Minigames.get_wheel_price())
|> assign(:result, nil)
|> assign(:wheel_active?, Minigames.wheel_active?())}
{:ok,
socket
|> assign(:current_page, :wheel)
|> assign(:in_spin?, false)
|> assign(:attendee_tokens, socket.assigns.current_user.attendee.tokens)
|> assign(:wheel_price, Minigames.get_wheel_price())
|> assign(:result, nil)
|> assign(:wheel_active?, Minigames.wheel_active?())}
end
end

@impl true
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
defmodule SafiraWeb.Backoffice.AttendeeLive.IneligibleLive.FormComponent do
use SafiraWeb, :live_component

alias Safira.Accounts
import SafiraWeb.Components.Forms

@impl true
def render(assigns) do
~H"""
<div>
<.page
title="Eligibility"
subtitle={gettext("Eligibility settings for %{name}.", name: assigns.attendee.user.name)}
>
<.simple_form
for={@form}
id="ineligible-form"
phx-target={@myself}
phx-change="validate"
phx-submit="save"
>
<.field field={@form[:ineligible]} label="Ineligible" type="switch" />
<:actions>
<.button phx-disable-with="Saving...">
<%= gettext("Save Eligibility") %>
</.button>
</:actions>
</.simple_form>
</.page>
</div>
"""
end

@impl true
def mount(socket) do
{:ok, socket |> assign(:live_action, :default)}
end

@impl true
def update(%{attendee: attendee} = assigns, socket) do
form = Accounts.change_attendee(attendee, %{})

{:ok,
socket
|> assign(assigns)
|> assign_new(:form, fn ->
to_form(form)
end)}
end

@impl true
def handle_event(
"validate",
%{"attendee" => attendee_params},
socket
) do
changeset = Accounts.change_attendee(socket.assigns.attendee, attendee_params)

{:noreply,
socket
|> assign(:form, to_form(changeset, action: :validate))}
end

@impl true
def handle_event("save", %{"attendee" => attendee_params}, socket) do
attendee = socket.assigns.attendee

case Accounts.update_attendee(attendee, attendee_params) do
{:ok, _attendee} ->
{:noreply, socket |> push_navigate(to: socket.assigns.patch)}

{:error, %Ecto.Changeset{} = changeset} ->
{:noreply, assign(socket, form: to_form(changeset, action: :validate))}
end
end

@impl true
def handle_event("confirm-modal", _params, socket) do
{:noreply, assign(socket, live_action: :confirm_eligibility)}
end

def handle_event("cancel", _params, socket) do
{:noreply, assign(socket, live_action: :default)}
end
end
44 changes: 41 additions & 3 deletions lib/safira_web/live/backoffice/attendee_live/show.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
<.icon name="hero-currency-euro" class="w-5 h-5" />
</.button>
</.link>
<.link patch={~p"/dashboard/attendees/#{@attendee.id}/edit/eligibility"}>
<.button>
<.icon name="hero-check-badge" class="w-5 h-5" />
</.button>
</.link>
</.ensure_permissions>
<.button>
<.icon name="hero-flag" class="w-5 h-5" />
Expand All @@ -28,14 +33,31 @@
</div>
<div class="flex flex-row gap-2 py-1 text-sm items-center">
<.icon name="hero-circle-stack" class="w-5 h-5" />
<p><%= "#{@attendee.tokens} tokens" %></p>
<div class="flex flex-row">
<p><%= "#{@attendee.tokens} tokens" %></p>
<span :if={@attendee.ineligible} class="text-red-700">*</span>
</div>
</div>
<div class="flex flex-row gap-2 py-1 text-sm items-center">
<.icon name="hero-qr-code" class="w-5 h-5" />
<p><%= "#{@attendee.entries} entries" %></p>
<.icon name="hero-ticket" class="w-5 h-5" />
<div class="flex flex-row">
<p><%= "#{@attendee.entries} entries" %></p>
<span :if={@attendee.ineligible} class="text-red-700">*</span>
</div>
</div>
</div>
</div>
<div
:if={@attendee.ineligible}
class="flex flex-row items-center gap-2 max-w-96 bg-red-500/20 px-4 rounded-lg py-2 text-red-700"
>
<.icon name="hero-information-circle" class="w-6 h-6 flex-shrink-0" />
<p>
<%= gettext(
"*This attendee is not eligible to win daily prizes, play minigames that involve other attendees, or participate in the final draw."
) %>
</p>
</div>
</.page>

<.modal
Expand All @@ -53,3 +75,19 @@
patch={~p"/dashboard/attendees/#{@attendee.id}"}
/>
</.modal>

<.modal
:if={@live_action in [:eligibility_edit]}
id="attendee-tokens-modal"
show
on_cancel={JS.patch(~p"/dashboard/attendees/#{@attendee.id}")}
>
<.live_component
module={SafiraWeb.Backoffice.AttendeeLive.IneligibleLive.FormComponent}
id={@attendee.id}
current_user={@current_user}
action={@live_action}
attendee={@attendee}
patch={~p"/dashboard/attendees/#{@attendee.id}"}
/>
</.modal>
1 change: 1 addition & 0 deletions lib/safira_web/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ defmodule SafiraWeb.Router do
live "/", Index, :index
live "/:id", Show, :show
live "/:id/edit/tokens", Show, :tokens_edit
live "/:id/edit/eligibility", Show, :eligibility_edit
end

scope "/event", EventLive do
Expand Down
1 change: 1 addition & 0 deletions priv/repo/migrations/20240714161311_create_attendees.exs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ defmodule Safira.Repo.Migrations.CreateAttendees do
add :tokens, :integer, default: 0
add :entries, :integer, default: 0
add :cv, :string, null: true
add :ineligible, :boolean, default: false

add :course_id, references(:courses, type: :binary_id, on_delete: :delete_all)
add :user_id, references(:users, type: :binary_id, on_delete: :delete_all), null: false
Expand Down
Loading

0 comments on commit 12356a2

Please sign in to comment.