+ <.leaderboard_top_person entry={Enum.at(@entries, 1)} pos={2} />
+ <.leaderboard_top_person entry={Enum.at(@entries, 0)} winner={true} pos={1} />
+ <.leaderboard_top_person entry={Enum.at(@entries, 2)} pos={3} />
+
+ """
+ end
+
+ attr :entry, :map, required: true
+ attr :winner, :boolean, default: false
+ attr :pos, :integer, required: true
+
+ defp leaderboard_top_person(assigns) do
+ ~H"""
+ <%= if @entry do %>
+
+
+
+ #<%= @entry.position %>
+
+
+ <.avatar
+ handle={@entry.handle}
+ size={:sm}
+ class="bg-light/5 border-2 border-light/5 rounded-full"
+ link={~p"/app/user/#{@entry.handle}"}
+ />
+
+ <.link patch={~p"/dashboard/attendees/#{@entry.attendee_id}"}>
+
+ <%= @entry.name %>
+
+
+
+
+
+
+ <%= @entry.badges %>
+
+ <%= gettext(" badges") %>
+
+
+
+ <%= @entry.tokens %>
+
+ <%= gettext(" tokens") %>
+
+
+
+
+
+ """
+ end
+end
diff --git a/lib/safira_web/live/backoffice/attendee_live/leaderboard_live/index.ex b/lib/safira_web/live/backoffice/attendee_live/leaderboard_live/index.ex
new file mode 100644
index 000000000..29d224d40
--- /dev/null
+++ b/lib/safira_web/live/backoffice/attendee_live/leaderboard_live/index.ex
@@ -0,0 +1,126 @@
+defmodule SafiraWeb.Backoffice.AttendeeLive.LeaderboardLive.Index do
+ use SafiraWeb, :backoffice_view
+
+ alias Safira.{Contest, Event}
+ import SafiraWeb.Backoffice.LeaderboardLive.Components.{Leaderboard, DaySelector}
+
+ on_mount {SafiraWeb.StaffRoles, index: %{"attendees" => ["show_leaderboard"]}}
+
+ @limit 30
+
+ @impl true
+ def mount(_params, _session, socket) do
+ daily_prizes = Contest.list_daily_prizes()
+
+ days = Event.list_event_dates()
+
+ start_day_idx = get_start_day_idx(days)
+ leaderboard = Contest.leaderboard(Enum.at(days, start_day_idx), @limit)
+
+ {:ok,
+ socket
+ |> assign(:leaderboard, leaderboard)
+ |> assign(:current_page, :attendees)
+ |> assign(:current_day_str, display_current_day(days, start_day_idx))
+ |> assign(:current_day_index, start_day_idx)
+ |> assign(:days, days)
+ |> assign(:left_enabled, start_day_idx > 0)
+ |> assign(:right_enabled, start_day_idx < length(days) - 1)
+ |> assign(:daily_prizes, daily_prizes)
+ |> assign(:prizes, get_day_prizes(daily_prizes, Enum.at(days, start_day_idx)))}
+ end
+
+ @impl true
+ def handle_params(_params, _url, socket) do
+ {:noreply, socket}
+ end
+
+ @impl true
+ def handle_event("on_left", _, socket) do
+ if socket.assigns.current_day_index > 0 do
+ day = Enum.at(socket.assigns.days, socket.assigns.current_day_index - 1)
+
+ {:noreply,
+ socket
+ |> assign(:current_day_index, socket.assigns.current_day_index - 1)
+ |> assign(
+ :current_day_str,
+ display_current_day(socket.assigns.days, socket.assigns.current_day_index - 1)
+ )
+ |> assign(:left_enabled, socket.assigns.current_day_index > 1)
+ |> assign(:right_enabled, true)
+ |> assign(:prizes, get_day_prizes(socket.assigns.daily_prizes, day))
+ |> assign(:leaderboard, Contest.leaderboard(day, @limit))}
+ else
+ {:noreply, socket}
+ end
+ end
+
+ def handle_event("on_right", _, socket) do
+ if socket.assigns.current_day_index < length(socket.assigns.days) - 1 do
+ day = Enum.at(socket.assigns.days, socket.assigns.current_day_index + 1)
+
+ {:noreply,
+ socket
+ |> assign(:current_day_index, socket.assigns.current_day_index + 1)
+ |> assign(
+ :current_day_str,
+ display_current_day(socket.assigns.days, socket.assigns.current_day_index + 1)
+ )
+ |> assign(:left_enabled, true)
+ |> assign(
+ :right_enabled,
+ socket.assigns.current_day_index < length(socket.assigns.days) - 2
+ )
+ |> assign(:prizes, get_day_prizes(socket.assigns.daily_prizes, day))
+ |> assign(:leaderboard, Contest.leaderboard(day, @limit))}
+ else
+ {:noreply, socket}
+ end
+ end
+
+ defp get_start_day_idx(days) do
+ today = Date.utc_today()
+
+ idx = Enum.find_index(days, fn d -> d == today end)
+
+ if is_nil(idx) do
+ 0
+ else
+ idx
+ end
+ end
+
+ defp display_current_day(days, index) do
+ days
+ |> Enum.at(index)
+ |> format_date()
+ end
+
+ defp format_date(date) do
+ today = Timex.today()
+ yesterday = Timex.shift(today, days: -1)
+
+ cond do
+ Timex.equal?(date, today) ->
+ gettext("Today")
+
+ Timex.equal?(date, yesterday) ->
+ gettext("Yesterday")
+
+ true ->
+ Timex.format!(date, "{D} {Mshort}")
+ end
+ end
+
+ defp get_day_prizes(daily_prizes, day) do
+ daily_prizes
+ |> Enum.filter(fn dp ->
+ if is_nil(day) do
+ is_nil(dp.date)
+ else
+ dp.date == day
+ end
+ end)
+ end
+end
diff --git a/lib/safira_web/live/backoffice/attendee_live/leaderboard_live/index.html.heex b/lib/safira_web/live/backoffice/attendee_live/leaderboard_live/index.html.heex
new file mode 100644
index 000000000..211437785
--- /dev/null
+++ b/lib/safira_web/live/backoffice/attendee_live/leaderboard_live/index.html.heex
@@ -0,0 +1,20 @@
+<.page title="Leaderboard">
+
<.ensure_permissions user={@current_user} permissions={%{"minigames" => ["edit"]}}>
<.link
diff --git a/lib/safira_web/live/backoffice/minigames_live/show.ex b/lib/safira_web/live/backoffice/minigames_live/show.ex
new file mode 100644
index 000000000..cf756217e
--- /dev/null
+++ b/lib/safira_web/live/backoffice/minigames_live/show.ex
@@ -0,0 +1,30 @@
+defmodule SafiraWeb.Backoffice.MinigamesLive.Show do
+ use SafiraWeb, :backoffice_view
+
+ alias Safira.Store
+
+ import SafiraWeb.Helpers
+ import SafiraWeb.Components.Table
+ import SafiraWeb.Components.TableSearch
+
+ @impl true
+ def mount(_params, _session, socket) do
+ {:ok, socket}
+ end
+
+ @impl true
+ def handle_params(params, _, socket) do
+ case Store.list_items_type_prize(params) do
+ {:ok, {items, meta}} ->
+ {:noreply,
+ socket
+ |> assign(:meta, meta)
+ |> assign(:params, params)
+ |> assign(:current_page, :show)
+ |> stream(:items, items, reset: true)}
+
+ {:error, _} ->
+ {:noreply, socket}
+ end
+ end
+end
diff --git a/lib/safira_web/live/backoffice/minigames_live/show.html.heex b/lib/safira_web/live/backoffice/minigames_live/show.html.heex
new file mode 100644
index 000000000..87916bec9
--- /dev/null
+++ b/lib/safira_web/live/backoffice/minigames_live/show.html.heex
@@ -0,0 +1,57 @@
+<.page title="Drops">
+ <:actions>
+
+ <.table_search
+ id="drops-table-attendee-name-search"
+ params={@params}
+ field={:prize_name}
+ path={~p"/dashboard/minigames/drops"}
+ placeholder={gettext("Search for Prizes")}
+ />
+
+
+
+ <.table id="items-table" items={@streams.items} meta={@meta} params={@params}>
+ <:col :let={{_id, item}} label="Attendee" field={:attendee_name}>
+
+ <.avatar
+ handle={item.attendee.user.handle}
+ src={
+ Uploaders.UserPicture.url(
+ {item.attendee.user.picture, item.attendee.user},
+ :original,
+ signed: true
+ )
+ }
+ />
+
+
<%= item.attendee.user.name %>
+
@<%= item.attendee.user.handle %>
+
+
+
+ <:col :let={{_id, item}} label="Prize" field={:name}>
+ <%= item.prize.name %>
+
+ <:col :let={{_id, item}} sortable label="Gotten at" field={:inserted_at}>
+ <%= relative_datetime(item.inserted_at) %>
+
+ <:col :let={{_id, item}} label="Status">
+ <%= if item.redeemed_at do %>
+
+ <%= gettext("Delivered") %>
+
+ <% else %>
+
+ <%= gettext("Waiting") %>
+
+ <% end %>
+
+ <:action :let={{_id, item}}>
+
+ <.link navigate={~p"/dashboard/store/products/#{item}"}>Show
+
+
+
+
+
diff --git a/lib/safira_web/live/backoffice/prize_live/daily_live/form_component.ex b/lib/safira_web/live/backoffice/prize_live/daily_live/form_component.ex
index 37600a82f..b2b023866 100644
--- a/lib/safira_web/live/backoffice/prize_live/daily_live/form_component.ex
+++ b/lib/safira_web/live/backoffice/prize_live/daily_live/form_component.ex
@@ -1,4 +1,4 @@
-defmodule SafiraWeb.PrizeLive.Daily.FormComponent do
+defmodule SafiraWeb.PrizeLive.MinigamesLive.Daily.FormComponent do
@moduledoc false
use SafiraWeb, :live_component
diff --git a/lib/safira_web/live/backoffice/prize_live/form_component.ex b/lib/safira_web/live/backoffice/prize_live/form_component.ex
index 02cf22b22..27bf3d33d 100644
--- a/lib/safira_web/live/backoffice/prize_live/form_component.ex
+++ b/lib/safira_web/live/backoffice/prize_live/form_component.ex
@@ -1,4 +1,4 @@
-defmodule SafiraWeb.PrizeLive.FormComponent do
+defmodule SafiraWeb.PrizeLive.MinigamesLive.FormComponent do
use SafiraWeb, :live_component
alias Safira.Minigames
diff --git a/lib/safira_web/live/backoffice/prize_live/index.ex b/lib/safira_web/live/backoffice/prize_live/index.ex
index 64adb1337..1b31e7b10 100644
--- a/lib/safira_web/live/backoffice/prize_live/index.ex
+++ b/lib/safira_web/live/backoffice/prize_live/index.ex
@@ -1,4 +1,4 @@
-defmodule SafiraWeb.Backoffice.PrizeLive.Index do
+defmodule SafiraWeb.Backoffice.MinigamesLive.PrizeLive.Index do
use SafiraWeb, :backoffice_view
alias Safira.Minigames
diff --git a/lib/safira_web/router.ex b/lib/safira_web/router.ex
index bcc075ca6..18c80d809 100644
--- a/lib/safira_web/router.ex
+++ b/lib/safira_web/router.ex
@@ -171,6 +171,7 @@ defmodule SafiraWeb.Router do
end
scope "/attendees", AttendeeLive do
+ live "/leaderboard", LeaderboardLive.Index, :index
live "/", Index, :index
live "/:id", Show, :show
live "/:id/edit/tokens", Show, :tokens_edit
@@ -293,7 +294,10 @@ defmodule SafiraWeb.Router do
end
end
- scope "/minigames" do
+ scope "/minigames", MinigamesLive do
+ live "/", Index, :index
+ live "/drops", Show, :show
+
scope "/prizes", PrizeLive do
live "/", Index, :index
live "/new", Index, :new
@@ -314,22 +318,20 @@ defmodule SafiraWeb.Router do
end
scope "/wheel" do
- live "/", MinigamesLive.Index, :edit_wheel
- live "/drops", MinigamesLive.Index, :edit_wheel_drops
- live "/simulator", MinigamesLive.Index, :simulate_wheel
+ live "/", Index, :edit_wheel
+ live "/drops", Index, :edit_wheel_drops
+ live "/simulator", Index, :simulate_wheel
end
scope "/slots" do
- live "/", MinigamesLive.Index, :edit_slots
- live "/reels_icons", MinigamesLive.Index, :edit_slots_reel_icons_icons
- live "/reels_position", MinigamesLive.Index, :edit_slots_reel_icons_position
- live "/paytable", MinigamesLive.Index, :edit_slots_paytable
- live "/payline", MinigamesLive.Index, :edit_slots_payline
+ live "/", Index, :edit_slots
+ live "/reels_icons", Index, :edit_slots_reel_icons_icons
+ live "/reels_position", Index, :edit_slots_reel_icons_position
+ live "/paytable", Index, :edit_slots_paytable
+ live "/payline", Index, :edit_slots_payline
end
- live "/", MinigamesLive.Index, :index
-
- live "/coin_flip", MinigamesLive.Index, :edit_coin_flip
+ live "/coin_flip", Index, :edit_coin_flip
end
scope "/scanner", ScannerLive do