@@ -9,9 +9,11 @@ defmodule AlgoraWeb.Org.DashboardLive do
9
9
alias Algora.Accounts
10
10
alias Algora.Bounties
11
11
alias Algora.Contracts
12
+ alias Algora.Github
12
13
alias Algora.Types.USD
13
14
alias Algora.Validations
14
15
alias Algora.Workspace
16
+ alias AlgoraWeb.Components.Logos
15
17
16
18
require Logger
17
19
@@ -61,31 +63,80 @@ defmodule AlgoraWeb.Org.DashboardLive do
61
63
end
62
64
end
63
65
66
+ @ impl true
64
67
def mount ( _params , _session , socket ) do
68
+ % { current_org: current_org } = socket . assigns
69
+
65
70
experts =
66
- socket . assigns . current_user . tech_stack
71
+ current_org . tech_stack
67
72
|> List . first ( )
68
73
|> Accounts . list_experts ( )
69
74
|> Enum . take ( 6 )
70
75
76
+ installations = Workspace . list_installations_by ( connected_user_id: current_org . id , provider: "github" )
77
+
71
78
if connected? ( socket ) do
79
+ Phoenix.PubSub . subscribe ( Algora.PubSub , "auth:#{ socket . id } " )
72
80
Bounties . subscribe ( )
73
81
end
74
82
75
83
{ :ok ,
76
84
socket
85
+ |> assign ( :installations , installations )
86
+ |> assign ( :oauth_url , Github . authorize_url ( % { socket_id: socket . id } ) )
77
87
|> assign ( :bounty_form , to_form ( BountyForm . changeset ( % BountyForm { } , % { } ) ) )
78
88
|> assign ( :tip_form , to_form ( TipForm . changeset ( % TipForm { } , % { } ) ) )
79
89
|> assign ( :experts , experts )
80
90
|> assign_tickets ( )
81
91
|> assign_achievements ( ) }
82
92
end
83
93
94
+ @ impl true
84
95
def render ( assigns ) do
85
96
~H"""
86
97
< div class = "lg:pr-96 " >
87
98
< 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 != [ ] } >
89
140
< div class = "grid grid-cols-1 gap-8 md:grid-cols-2 " >
90
141
{ create_bounty ( assigns ) }
91
142
{ create_tip ( assigns ) }
@@ -191,6 +242,21 @@ defmodule AlgoraWeb.Org.DashboardLive do
191
242
"""
192
243
end
193
244
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
+
194
260
def handle_event ( "create_bounty" , % { "bounty_form" => params } , socket ) do
195
261
changeset =
196
262
% BountyForm { }
@@ -251,10 +317,6 @@ defmodule AlgoraWeb.Org.DashboardLive do
251
317
end
252
318
end
253
319
254
- def handle_info ( :bounties_updated , socket ) do
255
- { :noreply , assign_tickets ( socket ) }
256
- end
257
-
258
320
defp assign_tickets ( socket ) do
259
321
tickets =
260
322
Bounties.PrizePool . list (
@@ -271,6 +333,7 @@ defmodule AlgoraWeb.Org.DashboardLive do
271
333
272
334
status_fns = [
273
335
{ & personalize_status / 1 , "Personalize Algora" } ,
336
+ { & install_app_status / 1 , "Install the Algora app" } ,
274
337
{ & create_bounty_status / 1 , "Create a bounty" } ,
275
338
{ & reward_bounty_status / 1 , "Reward a bounty" } ,
276
339
{ & begin_collaboration_status / 1 , "Contract a #{ tech } developer" } ,
@@ -279,7 +342,7 @@ defmodule AlgoraWeb.Org.DashboardLive do
279
342
280
343
{ achievements , _ } =
281
344
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 )
283
346
284
347
result =
285
348
cond do
@@ -296,29 +359,36 @@ defmodule AlgoraWeb.Org.DashboardLive do
296
359
297
360
defp personalize_status ( _socket ) , do: :completed
298
361
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
301
371
[ ] -> :upcoming
302
372
_ -> :completed
303
373
end
304
374
end
305
375
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
308
378
[ ] -> :upcoming
309
379
_ -> :completed
310
380
end
311
381
end
312
382
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
315
385
[ ] -> :upcoming
316
386
_ -> :completed
317
387
end
318
388
end
319
389
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
322
392
[ ] -> :upcoming
323
393
_ -> :completed
324
394
end
0 commit comments