@@ -11,6 +11,7 @@ defmodule AlgoraWeb.ContractLive do
1111 alias Algora.Bounties.LineItem
1212 alias Algora.Chat
1313 alias Algora.Organizations.Member
14+ alias Algora.Payments
1415 alias Algora.Repo
1516 alias Algora.Util
1617 alias Algora.Workspace
@@ -47,6 +48,8 @@ defmodule AlgoraWeb.ContractLive do
4748 |> Repo . get! ( bounty_id )
4849 |> Repo . preload ( [ :owner , :creator , :transactions , ticket: [ repository: [ :user ] ] ] )
4950
51+ timezone = if ( params = get_connect_params ( socket ) , do: params [ "timezone" ] )
52+
5053 { host , ticket_ref } =
5154 if bounty . ticket . repository do
5255 { bounty . ticket . repository . user ,
@@ -63,6 +66,7 @@ defmodule AlgoraWeb.ContractLive do
6366 |> assign ( :bounty , bounty )
6467 |> assign ( :ticket_ref , ticket_ref )
6568 |> assign ( :host , host )
69+ |> assign ( :timezone , timezone )
6670 |> on_mount ( bounty )
6771 end
6872
@@ -140,6 +144,7 @@ defmodule AlgoraWeb.ContractLive do
140144 |> assign ( :participants , participants )
141145 |> assign ( :reward_form , to_form ( reward_changeset ) )
142146 |> assign_contractor ( bounty . shared_with )
147+ |> assign_transactions ( )
143148 |> assign_line_items ( ) }
144149 end
145150
@@ -302,6 +307,51 @@ defmodule AlgoraWeb.ContractLive do
302307 </ div >
303308 </ . card_content >
304309 </ . card >
310+ < . card :if = { length ( @ transactions ) > 0 } >
311+ < . card_content >
312+ < div class = "-mx-6 overflow-x-auto " >
313+ < div class = "inline-block min-w-full py-2 align-middle " >
314+ < table class = "min-w-full divide-y divide-border " >
315+ < thead >
316+ < tr >
317+ < th scope = "col " class = "px-6 py-3.5 text-left text-sm font-semibold " > Date</ th >
318+ < th scope = "col " class = "px-6 py-3.5 text-left text-sm font-semibold " >
319+ Description
320+ </ th >
321+ < th scope = "col " class = "px-6 py-3.5 text-right text-sm font-semibold " >
322+ Amount
323+ </ th >
324+ </ tr >
325+ </ thead >
326+ < tbody class = "divide-y divide-border " >
327+ <%= for transaction <- @ transactions do %>
328+ < tr class = "hover:bg-muted/50 " >
329+ < td class = "whitespace-nowrap px-6 py-4 text-sm " >
330+ { Util . timestamp ( transaction . inserted_at , @ timezone ) }
331+ </ td >
332+ < td class = "whitespace-nowrap px-6 py-4 text-sm " >
333+ { description ( transaction ) }
334+ </ td >
335+ < td class = "font-display whitespace-nowrap px-6 py-4 text-right font-medium tabular-nums " >
336+ <%= case transaction_direction ( transaction . type ) do %>
337+ <% :plus -> %>
338+ < span class = "text-emerald-400 " >
339+ { Money . to_string! ( transaction . net_amount ) }
340+ </ span >
341+ <% :minus - > %>
342+ < span class = "text-foreground " >
343+ { Money . to_string! ( transaction . net_amount ) }
344+ </ span >
345+ <% end %>
346+ </ td >
347+ </ tr >
348+ <% end %>
349+ </ tbody >
350+ </ table >
351+ </ div >
352+ </ div >
353+ </ . card_content >
354+ </ . card >
305355 </ div >
306356 </ . scroll_area >
307357
@@ -556,4 +606,58 @@ defmodule AlgoraWeb.ContractLive do
556606
557607 assign ( socket , :contractor , contractor )
558608 end
609+
610+ defp assign_transactions ( socket ) do
611+ transactions =
612+ Payments . list_transactions (
613+ user_id: socket . assigns . bounty . owner . id ,
614+ status: :succeeded ,
615+ bounty_id: socket . assigns . bounty . id
616+ )
617+
618+ balance = calculate_balance ( transactions )
619+ volume = calculate_volume ( transactions )
620+
621+ socket
622+ |> assign ( :transactions , transactions )
623+ |> assign ( :total_balance , balance )
624+ |> assign ( :total_volume , volume )
625+ end
626+
627+ defp calculate_balance ( transactions ) do
628+ Enum . reduce ( transactions , Money . new! ( 0 , :USD ) , fn transaction , acc ->
629+ case transaction . type do
630+ type when type in [ :charge , :deposit , :credit ] ->
631+ Money . add! ( acc , transaction . net_amount )
632+
633+ type when type in [ :debit , :withdrawal , :transfer ] ->
634+ Money . sub! ( acc , transaction . net_amount )
635+
636+ _ ->
637+ acc
638+ end
639+ end )
640+ end
641+
642+ defp calculate_volume ( transactions ) do
643+ Enum . reduce ( transactions , Money . new! ( 0 , :USD ) , fn transaction , acc ->
644+ case transaction . type do
645+ type when type in [ :charge , :credit ] -> Money . add! ( acc , transaction . net_amount )
646+ _ -> acc
647+ end
648+ end )
649+ end
650+
651+ defp transaction_direction ( type ) do
652+ case type do
653+ t when t in [ :charge , :credit , :deposit ] -> :minus
654+ t when t in [ :debit , :withdrawal , :transfer ] -> :plus
655+ end
656+ end
657+
658+ defp description ( % { type: :charge } ) , do: "Escrowed"
659+
660+ defp description ( % { type: :debit } ) , do: "Released"
661+
662+ defp description ( % { type: _type } ) , do: nil
559663end
0 commit comments