@@ -31,13 +31,13 @@ defmodule AlgoraWeb.ClaimLive do
31
31
|> Enum . map ( & & 1 . amount )
32
32
|> Enum . reduce ( Money . zero ( :USD , no_fraction_if_integer: true ) , & Money . add! ( & 1 , & 2 ) )
33
33
34
- credits =
34
+ debits =
35
35
claims
36
36
|> Enum . flat_map ( & & 1 . transactions )
37
- |> Enum . filter ( & ( & 1 . type == :credit and & 1 . status == :succeeded ) )
37
+ |> Enum . filter ( & ( & 1 . type == :debit and & 1 . status == :succeeded ) )
38
38
39
39
total_paid =
40
- credits
40
+ debits
41
41
|> Enum . map ( & & 1 . net_amount )
42
42
|> Enum . reduce ( Money . zero ( :USD , no_fraction_if_integer: true ) , & Money . add! ( & 1 , & 2 ) )
43
43
@@ -49,6 +49,47 @@ defmodule AlgoraWeb.ClaimLive do
49
49
_ -> primary_claim . source . description
50
50
end
51
51
52
+ pledges =
53
+ primary_claim . target . bounties
54
+ |> Enum . group_by ( & & 1 . owner . id )
55
+ |> Map . new ( fn { owner_id , bounties } ->
56
+ { owner_id ,
57
+ { hd ( bounties ) . owner ,
58
+ Enum . reduce ( bounties , Money . zero ( :USD , no_fraction_if_integer: true ) , & Money . add! ( & 1 . amount , & 2 ) ) } }
59
+ end )
60
+
61
+ payments =
62
+ debits
63
+ |> Enum . group_by ( & & 1 . user_id )
64
+ |> Map . new ( fn { user_id , debits } ->
65
+ { user_id , Enum . reduce ( debits , Money . zero ( :USD , no_fraction_if_integer: true ) , & Money . add! ( & 1 . net_amount , & 2 ) ) }
66
+ end )
67
+
68
+ sponsors =
69
+ pledges
70
+ |> Enum . map ( fn { sponsor_id , { sponsor , pledged } } ->
71
+ paid = Map . get ( payments , sponsor_id , Money . zero ( :USD , no_fraction_if_integer: true ) )
72
+ tipped = Money . sub! ( paid , pledged )
73
+
74
+ status =
75
+ cond do
76
+ Money . equal? ( paid , pledged ) -> :paid
77
+ Money . positive? ( tipped ) -> :overpaid
78
+ Money . positive? ( paid ) -> :partial
79
+ primary_claim . status == :approved -> :pending
80
+ true -> :none
81
+ end
82
+
83
+ % {
84
+ sponsor: sponsor ,
85
+ status: status ,
86
+ pledged: pledged ,
87
+ paid: paid ,
88
+ tipped: tipped
89
+ }
90
+ end )
91
+ |> Enum . sort_by ( & { & 1 . pledged , & 1 . paid , & 1 . sponsor . name } , :desc )
92
+
52
93
{ :ok ,
53
94
socket
54
95
|> assign ( :page_title , primary_claim . source . title )
@@ -59,7 +100,8 @@ defmodule AlgoraWeb.ClaimLive do
59
100
|> assign ( :bounties , primary_claim . target . bounties )
60
101
|> assign ( :prize_pool , prize_pool )
61
102
|> assign ( :total_paid , total_paid )
62
- |> assign ( :source_body_html , source_body_html ) }
103
+ |> assign ( :source_body_html , source_body_html )
104
+ |> assign ( :sponsors , sponsors ) }
63
105
end
64
106
end
65
107
@@ -91,8 +133,16 @@ defmodule AlgoraWeb.ClaimLive do
91
133
</ div >
92
134
</ div >
93
135
< div class = "mt-4 grid grid-cols-2 gap-8 " >
94
- < . stat_card title = "Total Paid " value = { Money . to_string! ( @ total_paid ) } />
95
- < . stat_card title = "Prize Pool " value = { Money . to_string! ( @ prize_pool ) } />
136
+ < . stat_card title = "Total Paid " >
137
+ < div class = "text-success " >
138
+ { Money . to_string! ( @ total_paid ) }
139
+ </ div >
140
+ </ . stat_card >
141
+ < . stat_card title = "Prize Pool " >
142
+ < div class = "text-success " >
143
+ { Money . to_string! ( @ prize_pool ) }
144
+ </ div >
145
+ </ . stat_card >
96
146
</ div >
97
147
</ div >
98
148
</ . header >
@@ -118,7 +168,6 @@ defmodule AlgoraWeb.ClaimLive do
118
168
</ . card_header >
119
169
< . card_content >
120
170
< div class = "space-y-6 " >
121
- <%!-- Pull Request Details --%>
122
171
< div class = "space-y-4 " >
123
172
< . link
124
173
href = { @ source . url }
@@ -172,23 +221,72 @@ defmodule AlgoraWeb.ClaimLive do
172
221
</ . card_header >
173
222
< . card_content >
174
223
< div class = "divide-y divide-border " >
175
- <%= for bounty <- Enum . sort_by ( @ bounties , & { & 1 . amount , & 1 . inserted_at } , :desc ) do %>
224
+ <%= for sponsor <- @ sponsors do %>
176
225
< div class = "flex items-center justify-between py-4 " >
177
226
< div class = "flex items-center gap-4 " >
178
227
< . avatar >
179
- < . avatar_image src = { bounty . owner . avatar_url } />
228
+ < . avatar_image src = { sponsor . sponsor . avatar_url } />
180
229
< . avatar_fallback >
181
- { String . first ( bounty . owner . name ) }
230
+ { String . first ( sponsor . sponsor . name ) }
182
231
</ . avatar_fallback >
183
232
</ . avatar >
184
233
< div >
185
- < p class = "font-medium " > { bounty . owner . name } </ p >
186
- < p class = "text-sm text-muted-foreground " > @{ bounty . owner . handle } </ p >
234
+ < p class = "font-medium " > { sponsor . sponsor . name } </ p >
235
+ < p class = "text-sm text-muted-foreground " > @{ sponsor . sponsor . handle } </ p >
236
+ </ div >
237
+ </ div >
238
+ < div class = "text-right " >
239
+ < div class = "text-sm font-medium " >
240
+ <%= case sponsor . status do %>
241
+ <% :overpaid -> %>
242
+ < div class = "text-success " >
243
+ < span class = "text-base font-semibold font-display tabular-nums " >
244
+ { Money . to_string! ( Money . sub! ( sponsor . paid , sponsor . tipped ) ) }
245
+ </ span >
246
+ paid
247
+ </ div >
248
+ < div class = "text-success " >
249
+ < span class = "text-base font-semibold font-display tabular-nums " >
250
+ +{ Money . to_string! ( sponsor . tipped ) }
251
+ </ span >
252
+ tip!
253
+ </ div >
254
+ <% :paid - > %>
255
+ < div class = "text-success " >
256
+ < span class = "text-base font-semibold font-display tabular-nums " >
257
+ { Money . to_string! ( sponsor . paid ) }
258
+ </ span >
259
+ paid
260
+ </ div >
261
+ <% :partial - > %>
262
+ < div class = "text-success " >
263
+ < span class = "text-base font-semibold font-display tabular-nums " >
264
+ { Money . to_string! ( sponsor . paid ) }
265
+ </ span >
266
+ paid
267
+ </ div >
268
+ < div class = "text-muted-foreground " >
269
+ < span class = "text-base font-semibold font-display tabular-nums " >
270
+ { Money . to_string! ( Money . sub! ( sponsor . pledged , sponsor . paid ) ) }
271
+ </ span >
272
+ pending
273
+ </ div >
274
+ <% :pending - > %>
275
+ < div class = "text-muted-foreground " >
276
+ < span class = "text-base font-semibold font-display tabular-nums " >
277
+ { Money . to_string! ( sponsor . pledged ) }
278
+ </ span >
279
+ pending
280
+ </ div >
281
+ <% :none - > %>
282
+ < div class = "text-success " >
283
+ < span class = "text-base font-semibold font-display tabular-nums " >
284
+ { Money . to_string! ( sponsor . pledged ) }
285
+ </ span >
286
+ </ div >
287
+ <% end %>
187
288
</ div >
188
289
</ div >
189
- < . badge variant = "success " class = "font-display " >
190
- { Money . to_string! ( bounty . amount ) }
191
- </ . badge >
192
290
</ div >
193
291
<% end %>
194
292
</ div >
0 commit comments