Skip to content

Commit d202702

Browse files
committed
feat: add prompt to install the app
1 parent 0a6731b commit d202702

File tree

2 files changed

+86
-16
lines changed

2 files changed

+86
-16
lines changed

lib/algora_web/controllers/installation_callback_controller.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,5 +78,5 @@ defmodule AlgoraWeb.InstallationCallbackController do
7878
end
7979
end
8080

81-
defp redirect_url(conn), do: ~p"/org/#{User.last_context(conn.assigns.current_user)}/settings"
81+
defp redirect_url(conn), do: ~p"/org/#{User.last_context(conn.assigns.current_user)}"
8282
end

lib/algora_web/live/org/dashboard_live.ex

Lines changed: 85 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@ defmodule AlgoraWeb.Org.DashboardLive do
99
alias Algora.Accounts
1010
alias Algora.Bounties
1111
alias Algora.Contracts
12+
alias Algora.Github
1213
alias Algora.Types.USD
1314
alias Algora.Validations
1415
alias Algora.Workspace
16+
alias AlgoraWeb.Components.Logos
1517

1618
require Logger
1719

@@ -61,31 +63,80 @@ defmodule AlgoraWeb.Org.DashboardLive do
6163
end
6264
end
6365

66+
@impl true
6467
def mount(_params, _session, socket) do
68+
%{current_org: current_org} = socket.assigns
69+
6570
experts =
66-
socket.assigns.current_user.tech_stack
71+
current_org.tech_stack
6772
|> List.first()
6873
|> Accounts.list_experts()
6974
|> Enum.take(6)
7075

76+
installations = Workspace.list_installations_by(connected_user_id: current_org.id, provider: "github")
77+
7178
if connected?(socket) do
79+
Phoenix.PubSub.subscribe(Algora.PubSub, "auth:#{socket.id}")
7280
Bounties.subscribe()
7381
end
7482

7583
{:ok,
7684
socket
85+
|> assign(:installations, installations)
86+
|> assign(:oauth_url, Github.authorize_url(%{socket_id: socket.id}))
7787
|> assign(:bounty_form, to_form(BountyForm.changeset(%BountyForm{}, %{})))
7888
|> assign(:tip_form, to_form(TipForm.changeset(%TipForm{}, %{})))
7989
|> assign(:experts, experts)
8090
|> assign_tickets()
8191
|> assign_achievements()}
8292
end
8393

94+
@impl true
8495
def render(assigns) do
8596
~H"""
8697
<div class="lg:pr-96">
8798
<div class="container mx-auto max-w-7xl space-y-8 p-8">
88-
<.section>
99+
<.section :if={@installations == []}>
100+
<.card>
101+
<.card_header>
102+
<.card_title>GitHub Integration</.card_title>
103+
<.card_description :if={@installations == []}>
104+
Install the Algora app to enable slash commands in your GitHub repositories
105+
</.card_description>
106+
</.card_header>
107+
<.card_content>
108+
<div class="flex flex-col gap-3">
109+
<%= if @installations != [] do %>
110+
<%= for installation <- @installations do %>
111+
<div class="flex items-center gap-2">
112+
<img src={installation.avatar_url} class="w-9 h-9 rounded-lg" />
113+
<div>
114+
<p class="font-medium">{installation.provider_meta["account"]["login"]}</p>
115+
<p class="text-sm text-muted-foreground">
116+
Algora app is installed in
117+
<strong>{installation.repository_selection}</strong>
118+
repositories
119+
</p>
120+
</div>
121+
</div>
122+
<% end %>
123+
<.button phx-click="install_app" class="ml-auto gap-2">
124+
<Logos.github class="w-4 h-4 mr-2 -ml-1" />
125+
Manage {ngettext("installation", "installations", length(@installations))}
126+
</.button>
127+
<% else %>
128+
<div class="flex flex-col gap-2">
129+
<.button phx-click="install_app" class="ml-auto gap-2">
130+
<Logos.github class="w-4 h-4 mr-2 -ml-1" /> Install GitHub App
131+
</.button>
132+
</div>
133+
<% end %>
134+
</div>
135+
</.card_content>
136+
</.card>
137+
</.section>
138+
139+
<.section :if={@installations != []}>
89140
<div class="grid grid-cols-1 gap-8 md:grid-cols-2">
90141
{create_bounty(assigns)}
91142
{create_tip(assigns)}
@@ -191,6 +242,21 @@ defmodule AlgoraWeb.Org.DashboardLive do
191242
"""
192243
end
193244

245+
@impl true
246+
def handle_info(:bounties_updated, socket) do
247+
{:noreply, assign_tickets(socket)}
248+
end
249+
250+
def handle_info({:authenticated, user}, socket) do
251+
{:noreply, socket |> assign(:current_user, user) |> redirect(external: Github.install_url_select_target())}
252+
end
253+
254+
@impl true
255+
def handle_event("install_app", _params, socket) do
256+
# TODO: immediately redirect to install_url if user has valid token
257+
{:noreply, push_event(socket, "open_popup", %{url: socket.assigns.oauth_url})}
258+
end
259+
194260
def handle_event("create_bounty", %{"bounty_form" => params}, socket) do
195261
changeset =
196262
%BountyForm{}
@@ -251,10 +317,6 @@ defmodule AlgoraWeb.Org.DashboardLive do
251317
end
252318
end
253319

254-
def handle_info(:bounties_updated, socket) do
255-
{:noreply, assign_tickets(socket)}
256-
end
257-
258320
defp assign_tickets(socket) do
259321
tickets =
260322
Bounties.PrizePool.list(
@@ -271,6 +333,7 @@ defmodule AlgoraWeb.Org.DashboardLive do
271333

272334
status_fns = [
273335
{&personalize_status/1, "Personalize Algora"},
336+
{&install_app_status/1, "Install the Algora app"},
274337
{&create_bounty_status/1, "Create a bounty"},
275338
{&reward_bounty_status/1, "Reward a bounty"},
276339
{&begin_collaboration_status/1, "Contract a #{tech} developer"},
@@ -279,7 +342,7 @@ defmodule AlgoraWeb.Org.DashboardLive do
279342

280343
{achievements, _} =
281344
Enum.reduce_while(status_fns, {[], false}, fn {status_fn, name}, {acc, found_current} ->
282-
status = status_fn.(socket.assigns.current_user)
345+
status = status_fn.(socket)
283346

284347
result =
285348
cond do
@@ -296,29 +359,36 @@ defmodule AlgoraWeb.Org.DashboardLive do
296359

297360
defp personalize_status(_socket), do: :completed
298361

299-
defp create_bounty_status(user) do
300-
case Bounties.list_bounties(owner_id: user.id, limit: 1) do
362+
defp install_app_status(socket) do
363+
case socket.assigns.installations do
364+
[] -> :upcoming
365+
_ -> :completed
366+
end
367+
end
368+
369+
defp create_bounty_status(socket) do
370+
case Bounties.list_bounties(owner_id: socket.assigns.current_user.id, limit: 1) do
301371
[] -> :upcoming
302372
_ -> :completed
303373
end
304374
end
305375

306-
defp reward_bounty_status(user) do
307-
case Bounties.list_bounties(owner_id: user.id, status: :paid, limit: 1) do
376+
defp reward_bounty_status(socket) do
377+
case Bounties.list_bounties(owner_id: socket.assigns.current_user.id, status: :paid, limit: 1) do
308378
[] -> :upcoming
309379
_ -> :completed
310380
end
311381
end
312382

313-
defp begin_collaboration_status(user) do
314-
case Contracts.list_contracts(client_id: user.id, active_or_paid?: true, limit: 1) do
383+
defp begin_collaboration_status(socket) do
384+
case Contracts.list_contracts(client_id: socket.assigns.current_user.id, active_or_paid?: true, limit: 1) do
315385
[] -> :upcoming
316386
_ -> :completed
317387
end
318388
end
319389

320-
defp complete_first_contract_status(user) do
321-
case Contracts.list_contracts(client_id: user.id, status: :paid, limit: 1) do
390+
defp complete_first_contract_status(socket) do
391+
case Contracts.list_contracts(client_id: socket.assigns.current_user.id, status: :paid, limit: 1) do
322392
[] -> :upcoming
323393
_ -> :completed
324394
end

0 commit comments

Comments
 (0)