Skip to content

Commit 91390e6

Browse files
committed
allow any payment at any time after initial contract cycle
1 parent bdbea47 commit 91390e6

File tree

1 file changed

+120
-24
lines changed

1 file changed

+120
-24
lines changed

lib/algora_web/live/contract_live.ex

Lines changed: 120 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,13 @@ defmodule AlgoraWeb.ContractLive do
1313
alias Algora.Organizations.Member
1414
alias Algora.Payments
1515
alias Algora.Repo
16+
alias Algora.Types.USD
1617
alias Algora.Util
1718
alias Algora.Workspace
1819

1920
require Logger
2021

21-
# defp tip_options, do: [{"None", 0}, {"10%", 10}, {"20%", 20}, {"50%", 50}]
22+
defp tip_options, do: [{"None", 0}, {"10%", 10}, {"20%", 20}, {"50%", 50}]
2223

2324
defmodule RewardBountyForm do
2425
@moduledoc false
@@ -28,7 +29,7 @@ defmodule AlgoraWeb.ContractLive do
2829

2930
@primary_key false
3031
embedded_schema do
31-
field :amount, Algora.Types.USD
32+
field :amount, USD
3233
field :tip_percentage, :decimal
3334
end
3435

@@ -108,8 +109,7 @@ defmodule AlgoraWeb.ContractLive do
108109

109110
ticket_body_html = Algora.Markdown.render(bounty.ticket.description)
110111

111-
reward_changeset =
112-
RewardBountyForm.changeset(%RewardBountyForm{}, %{amount: bounty.amount})
112+
reward_changeset = RewardBountyForm.changeset(%RewardBountyForm{}, %{amount: bounty.amount, tip_percentage: 0})
113113

114114
{:ok, thread} = Chat.get_or_create_bounty_thread(bounty)
115115
messages = thread.id |> Chat.list_messages() |> Repo.preload(:sender)
@@ -138,6 +138,7 @@ defmodule AlgoraWeb.ContractLive do
138138
|> assign(:total_paid, total_paid)
139139
|> assign(:ticket_body_html, ticket_body_html)
140140
|> assign(:show_reward_modal, false)
141+
|> assign(:show_authorize_modal, false)
141142
|> assign(:selected_context, nil)
142143
|> assign(:line_items, [])
143144
|> assign(:thread, thread)
@@ -146,7 +147,7 @@ defmodule AlgoraWeb.ContractLive do
146147
|> assign(:reward_form, to_form(reward_changeset))
147148
|> assign_contractor(bounty.shared_with)
148149
|> assign_transactions()
149-
|> assign_line_items()}
150+
|> assign_line_items(reward_changeset)}
150151
end
151152

152153
@impl true
@@ -200,22 +201,24 @@ defmodule AlgoraWeb.ContractLive do
200201
{:noreply, assign(socket, :show_reward_modal, true)}
201202
end
202203

204+
@impl true
205+
def handle_event("authorize", _params, socket) do
206+
{:noreply, assign(socket, :show_authorize_modal, true)}
207+
end
208+
203209
@impl true
204210
def handle_event("close_drawer", _params, socket) do
205211
{:noreply, close_drawers(socket)}
206212
end
207213

208214
@impl true
209215
def handle_event("validate_reward", %{"reward_bounty_form" => params}, socket) do
216+
changeset = RewardBountyForm.changeset(%RewardBountyForm{}, params)
217+
210218
{:noreply,
211219
socket
212-
|> assign(:reward_form, to_form(RewardBountyForm.changeset(%RewardBountyForm{}, params)))
213-
|> assign_line_items()}
214-
end
215-
216-
@impl true
217-
def handle_event("assign_line_items", %{"reward_bounty_form" => _params}, socket) do
218-
{:noreply, assign_line_items(socket)}
220+
|> assign(:reward_form, to_form(changeset))
221+
|> assign_line_items(changeset)}
219222
end
220223

221224
@impl true
@@ -345,9 +348,11 @@ defmodule AlgoraWeb.ContractLive do
345348
<% end %>
346349
347350
<%= if _transaction = Enum.find(@transactions, fn tx -> tx.type == :debit end) do %>
348-
<.badge variant="success" class="mb-auto">
349-
Active
350-
</.badge>
351+
<div class="flex flex-col gap-4 items-end">
352+
<.badge variant="success" class="mb-auto">
353+
Active
354+
</.badge>
355+
</div>
351356
<% end %>
352357
</div>
353358
</.card_content>
@@ -404,7 +409,7 @@ defmodule AlgoraWeb.ContractLive do
404409
</div>
405410
</dt>
406411
</div>
407-
<.button phx-click="reward">
412+
<.button phx-click="authorize">
408413
Authorize
409414
</.button>
410415
</dl>
@@ -414,7 +419,16 @@ defmodule AlgoraWeb.ContractLive do
414419
<.card :if={length(@transactions) > 0}>
415420
<.card_header>
416421
<.card_title>
417-
Timeline
422+
<div class="flex justify-between gap-4">
423+
Timeline
424+
<%= if @can_create_bounty do %>
425+
<%= if _transaction = Enum.find(@transactions, fn tx -> tx.type == :debit and tx.status == :succeeded end) do %>
426+
<.button phx-click="reward">
427+
Make payment
428+
</.button>
429+
<% end %>
430+
<% end %>
431+
</div>
418432
</.card_title>
419433
</.card_header>
420434
<.card_content class="pt-0">
@@ -589,7 +603,7 @@ defmodule AlgoraWeb.ContractLive do
589603
</div>
590604
</div>
591605
592-
<.drawer :if={@current_user} show={@show_reward_modal} on_cancel="close_drawer">
606+
<.drawer :if={@current_user} show={@show_authorize_modal} on_cancel="close_drawer">
593607
<.drawer_header>
594608
<.drawer_title>Authorize payment</.drawer_title>
595609
<.drawer_description>
@@ -612,8 +626,88 @@ defmodule AlgoraWeb.ContractLive do
612626
field={@reward_form[:amount]}
613627
disabled
614628
/>
629+
</div>
630+
</.card_content>
631+
</.card>
632+
<.card>
633+
<.card_header>
634+
<.card_title>Payment Summary</.card_title>
635+
</.card_header>
636+
<.card_content class="pt-0">
637+
<dl class="space-y-4">
638+
<%= for line_item <- @line_items do %>
639+
<div class="flex justify-between">
640+
<dt class="flex items-center gap-4">
641+
<%= if line_item.image do %>
642+
<.avatar>
643+
<.avatar_image src={line_item.image} />
644+
<.avatar_fallback>
645+
{Util.initials(line_item.title)}
646+
</.avatar_fallback>
647+
</.avatar>
648+
<% else %>
649+
<div class="w-10" />
650+
<% end %>
651+
<div>
652+
<div class="font-medium">{line_item.title}</div>
653+
<div class="text-muted-foreground text-sm">{line_item.description}</div>
654+
</div>
655+
</dt>
656+
<dd class="font-display font-semibold tabular-nums">
657+
{Money.to_string!(line_item.amount)}
658+
</dd>
659+
</div>
660+
<% end %>
661+
<div class="h-px bg-border" />
662+
<div class="flex justify-between">
663+
<dt class="flex items-center gap-4">
664+
<div class="w-10" />
665+
<div class="font-medium">Total due</div>
666+
</dt>
667+
<dd class="font-display font-semibold tabular-nums">
668+
{LineItem.gross_amount(@line_items)}
669+
</dd>
670+
</div>
671+
</dl>
672+
</.card_content>
673+
</.card>
674+
</div>
675+
<div class="ml-auto flex gap-4">
676+
<.button variant="secondary" phx-click="close_drawer" type="button">
677+
Cancel
678+
</.button>
679+
<.button type="submit">
680+
Authorize with Stripe <.icon name="tabler-arrow-right" class="-mr-1 ml-2 h-4 w-4" />
681+
</.button>
682+
</div>
683+
</div>
684+
</.form>
685+
</.drawer_content>
686+
</.drawer>
687+
<.drawer :if={@current_user} show={@show_reward_modal} on_cancel="close_drawer">
688+
<.drawer_header>
689+
<.drawer_title>Pay contract</.drawer_title>
690+
<.drawer_description>
691+
You can pay any amount at any time.
692+
</.drawer_description>
693+
</.drawer_header>
694+
<.drawer_content class="mt-4">
695+
<.form for={@reward_form} phx-change="validate_reward" phx-submit="pay_with_stripe">
696+
<div class="flex flex-col gap-8">
697+
<div class="grid grid-cols-2 gap-8">
698+
<.card>
699+
<.card_header>
700+
<.card_title>Payment Details</.card_title>
701+
</.card_header>
702+
<.card_content class="pt-0">
703+
<div class="space-y-4">
704+
<.input
705+
label="Amount"
706+
icon="tabler-currency-dollar"
707+
field={@reward_form[:amount]}
708+
/>
615709
616-
<%!-- <div>
710+
<div>
617711
<.label>Tip</.label>
618712
<div class="mt-2">
619713
<.radio_group
@@ -622,7 +716,7 @@ defmodule AlgoraWeb.ContractLive do
622716
options={tip_options()}
623717
/>
624718
</div>
625-
</div> --%>
719+
</div>
626720
</div>
627721
</.card_content>
628722
</.card>
@@ -674,7 +768,7 @@ defmodule AlgoraWeb.ContractLive do
674768
Cancel
675769
</.button>
676770
<.button type="submit">
677-
Authorize with Stripe <.icon name="tabler-arrow-right" class="-mr-1 ml-2 h-4 w-4" />
771+
Pay with Stripe <.icon name="tabler-arrow-right" class="-mr-1 ml-2 h-4 w-4" />
678772
</.button>
679773
</div>
680774
</div>
@@ -684,12 +778,12 @@ defmodule AlgoraWeb.ContractLive do
684778
"""
685779
end
686780

687-
defp assign_line_items(socket) do
781+
defp assign_line_items(socket, changeset) do
688782
line_items =
689783
Bounties.generate_line_items(
690784
%{
691785
owner: socket.assigns.bounty.owner,
692-
amount: calculate_final_amount(socket.assigns.reward_form.source)
786+
amount: calculate_final_amount(changeset)
693787
},
694788
bounty: socket.assigns.bounty,
695789
ticket_ref: socket.assigns.ticket_ref,
@@ -728,7 +822,9 @@ defmodule AlgoraWeb.ContractLive do
728822
end
729823

730824
defp close_drawers(socket) do
731-
assign(socket, :show_reward_modal, false)
825+
socket
826+
|> assign(:show_reward_modal, false)
827+
|> assign(:show_authorize_modal, false)
732828
end
733829

734830
defp assign_contractor(socket, shared_with) do

0 commit comments

Comments
 (0)