Skip to content

Commit 4f405cd

Browse files
committed
feat: org leaderboard page
1 parent 9d10062 commit 4f405cd

File tree

4 files changed

+92
-0
lines changed

4 files changed

+92
-0
lines changed

lib/algora_web/live/org/dashboard_public_live.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ defmodule AlgoraWeb.Org.DashboardPublicLive do
9393
title="Solvers"
9494
value={@stats.solvers_count}
9595
subtext={"+#{@stats.solvers_diff} from last month"}
96+
navigate={~p"/org/#{@org.handle}/leaderboard"}
9697
icon="tabler-user-code"
9798
/>
9899
<.stat_card
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
defmodule AlgoraWeb.Org.LeaderboardLive do
2+
@moduledoc false
3+
use AlgoraWeb, :live_view
4+
5+
alias Algora.Accounts
6+
alias Algora.Accounts.User
7+
alias Algora.Organizations
8+
9+
def mount(%{"org_handle" => handle}, _session, socket) do
10+
org = Organizations.get_org_by_handle!(handle)
11+
top_earners = Accounts.list_developers(org_id: org.id, earnings_gt: Money.zero(:USD))
12+
13+
{:ok,
14+
socket
15+
|> assign(:page_title, "Leaderboard")
16+
|> assign(:org, org)
17+
|> assign(:top_earners, top_earners)}
18+
end
19+
20+
def render(assigns) do
21+
~H"""
22+
<div class="container mx-auto max-w-7xl space-y-6 p-6">
23+
<div class="space-y-1">
24+
<h1 class="text-2xl font-bold"></h1>
25+
<p class="text-muted-foreground"></p>
26+
</div>
27+
28+
<.card>
29+
<.card_header>
30+
<.card_title>Leaderboard</.card_title>
31+
<.card_description>
32+
Top contributors ranked by earnings from bounties, tips, and contracts
33+
</.card_description>
34+
</.card_header>
35+
<.card_content>
36+
<div class="-mx-6 overflow-x-auto">
37+
<div class="inline-block min-w-full py-2 align-middle">
38+
<table class="min-w-full divide-y divide-border">
39+
<thead>
40+
<tr>
41+
<th scope="col" class="px-6 py-3.5 text-left text-sm font-semibold">Rank</th>
42+
<th scope="col" class="px-6 py-3.5 text-left text-sm font-semibold">
43+
Contributor
44+
</th>
45+
<th scope="col" class="px-6 py-3.5 text-left text-sm font-semibold">
46+
Total Earned
47+
</th>
48+
</tr>
49+
</thead>
50+
<tbody class="divide-y divide-border">
51+
<tr :for={{earner, idx} <- Enum.with_index(@top_earners)}>
52+
<td class="whitespace-nowrap px-6 py-4">
53+
<div class="font-mono text-muted-foreground">#{idx + 1}</div>
54+
</td>
55+
<td class="whitespace-nowrap px-6 py-4">
56+
<div class="flex items-center gap-3">
57+
<.avatar>
58+
<.avatar_image src={earner.avatar_url} />
59+
<.avatar_fallback>
60+
{String.slice(User.handle(earner), 0, 2)}
61+
</.avatar_fallback>
62+
</.avatar>
63+
<div>
64+
<div class="font-medium">{earner.name} {earner.flag}</div>
65+
<div class="text-sm text-muted-foreground">@{User.handle(earner)}</div>
66+
</div>
67+
</div>
68+
</td>
69+
<td class="whitespace-nowrap px-6 py-4">
70+
<div class="font-display font-medium text-success">
71+
{Money.to_string!(earner.total_earned)}
72+
</div>
73+
</td>
74+
</tr>
75+
</tbody>
76+
</table>
77+
</div>
78+
</div>
79+
</.card_content>
80+
</.card>
81+
</div>
82+
"""
83+
end
84+
end

lib/algora_web/live/org/nav.ex

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@ defmodule AlgoraWeb.Org.Nav do
7676
icon: "tabler-diamond",
7777
label: "Bounties"
7878
},
79+
%{
80+
href: "/org/#{org_handle}/leaderboard",
81+
tab: :leaderboard,
82+
icon: "tabler-trophy",
83+
label: "Leaderboard"
84+
},
7985
%{
8086
href: "/org/#{org_handle}/team",
8187
tab: :team,

lib/algora_web/router.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ defmodule AlgoraWeb.Router do
9292
live "/org/:org_handle/chat", ChatLive, :index
9393
live "/org/:org_handle/settings", Org.SettingsLive, :edit
9494
live "/org/:org_handle/team", Org.TeamLive, :index
95+
live "/org/:org_handle/leaderboard", Org.LeaderboardLive, :index
9596
end
9697

9798
live_session :org2,

0 commit comments

Comments
 (0)