@@ -6,11 +6,13 @@ defmodule AlgoraWeb.Admin.CampaignLive do
6
6
import Ecto.Changeset
7
7
import Ecto.Query
8
8
9
+ alias Algora.Accounts
9
10
alias Algora.Activities.Jobs.SendCampaignEmail
10
11
alias Algora.Admin
11
12
alias Algora.Mailer
12
13
alias Algora.Repo
13
14
alias Algora.Settings
15
+ alias Algora.Util
14
16
alias Algora.Workspace
15
17
alias Algora.Workspace.Repository
16
18
alias AlgoraWeb.LocalStore
@@ -45,11 +47,15 @@ defmodule AlgoraWeb.Admin.CampaignLive do
45
47
46
48
@ impl true
47
49
def mount ( _params , _session , socket ) do
50
+ timezone = if ( params = get_connect_params ( socket ) , do: params [ "timezone" ] )
51
+
48
52
{ :ok ,
49
53
socket
54
+ |> assign ( :timezone , timezone )
50
55
|> assign ( :page_title , "Campaign" )
51
56
|> assign ( :form , to_form ( Campaign . changeset ( % Campaign { } ) ) )
52
57
|> assign ( :repo_cache , % { } )
58
+ |> assign ( :user_cache , % { } )
53
59
|> assign_preview ( ) }
54
60
end
55
61
@@ -188,10 +194,12 @@ defmodule AlgoraWeb.Admin.CampaignLive do
188
194
< . table id = "csv-data " rows = { @ csv_data } >
189
195
<: col
190
196
:let = { row }
191
- :for = { key <- @ csv_columns |> Enum . filter ( & ( & 1 != "repo_url" ) ) }
197
+ :for = {
198
+ key <- @ csv_columns |> Enum . filter ( & ( & 1 != "repo_url" and & 1 != "tech_stack" ) )
199
+ }
192
200
label = { key }
193
201
>
194
- < . cell value = { row [ key ] } />
202
+ < . cell value = { row [ key ] } timezone = { @ timezone } />
195
203
</: col >
196
204
<: action :let = { row } >
197
205
< . button type = "button " phx-click = "send_email " phx-value-email = { row [ "email" ] } >
@@ -217,6 +225,17 @@ defmodule AlgoraWeb.Admin.CampaignLive do
217
225
"""
218
226
end
219
227
228
+ defp cell ( % { value: % DateTime { } } = assigns ) do
229
+ ~H"""
230
+ < span :if = { @ timezone } class = "tabular-nums whitespace-nowrap text-sm " >
231
+ { Calendar . strftime (
232
+ DateTime . from_naive! ( @ value , "Etc/UTC" ) |> DateTime . shift_zone! ( @ timezone ) ,
233
+ "%Y/%m/%d, %H:%M:%S"
234
+ ) }
235
+ </ span >
236
+ """
237
+ end
238
+
220
239
defp cell ( assigns ) do
221
240
~H"""
222
241
< span class = "text-sm " >
@@ -229,7 +248,7 @@ defmodule AlgoraWeb.Admin.CampaignLive do
229
248
Enum . reduce ( data , template , fn { key , value } , acc ->
230
249
case value do
231
250
value when is_list ( value ) -> acc
232
- _ -> String . replace ( acc , "%{#{ key } }" , value )
251
+ _ -> String . replace ( acc , "%{#{ key } }" , to_string ( value ) )
233
252
end
234
253
end )
235
254
end
@@ -249,6 +268,39 @@ defmodule AlgoraWeb.Admin.CampaignLive do
249
268
250
269
defp repo_key ( _row ) , do: nil
251
270
271
+ defp assign_timestamps ( socket ) do
272
+ new_keys =
273
+ socket . assigns . csv_data
274
+ |> Enum . map ( & Map . get ( & 1 , "email" ) )
275
+ |> Enum . uniq ( )
276
+
277
+ new_cache =
278
+ Map . new ( new_keys , fn key ->
279
+ user = Accounts . get_user_by_email ( key )
280
+
281
+ if user do
282
+ { key , Util . next_occurrence_of_time ( user . last_active_at || user . inserted_at ) }
283
+ else
284
+ { key , Util . next_occurrence_of_time ( Util . random_datetime ( ) ) }
285
+ end
286
+ end )
287
+
288
+ updated_cache = Map . merge ( socket . assigns . user_cache , new_cache )
289
+
290
+ csv_data =
291
+ Enum . map ( socket . assigns . csv_data , fn row -> Map . put ( row , "timestamp" , Map . get ( updated_cache , row [ "email" ] ) ) end )
292
+
293
+ csv_columns =
294
+ csv_data
295
+ |> Enum . flat_map ( & Map . keys / 1 )
296
+ |> Enum . uniq ( )
297
+
298
+ socket
299
+ |> assign ( :repo_cache , updated_cache )
300
+ |> assign ( :csv_data , csv_data )
301
+ |> assign ( :csv_columns , csv_columns )
302
+ end
303
+
252
304
defp assign_repo_names ( socket ) do
253
305
new_keys =
254
306
socket . assigns . csv_data
@@ -342,6 +394,7 @@ defmodule AlgoraWeb.Admin.CampaignLive do
342
394
socket
343
395
|> assign ( :csv_data , csv_data )
344
396
|> assign_repo_names ( )
397
+ |> assign_timestamps ( )
345
398
end
346
399
347
400
defp assign_preview ( socket ) do
@@ -374,16 +427,16 @@ defmodule AlgoraWeb.Admin.CampaignLive do
374
427
id: Algora.Settings . get ( "email_campaign" ) [ "value" ] ,
375
428
subject: subject ,
376
429
recipient_email: recipient [ "email" ] ,
377
- recipient: Algora. Util. term_to_base64 ( recipient ) ,
430
+ recipient: Util . term_to_base64 ( recipient ) ,
378
431
template: template ,
379
432
from_name: from_name ,
380
433
from_email: from_email ,
381
- preheader: render_preview ( preheader , recipient )
434
+ preheader: render_preview ( preheader , recipient ) ,
435
+ scheduled_at: recipient [ "timestamp" ]
382
436
}
383
437
end )
384
- |> Enum . with_index ( )
385
- |> Enum . reduce_while ( :ok , fn { args , index } , acc ->
386
- case args |> SendCampaignEmail . new ( schedule_in: 5 * index ) |> Oban . insert ( ) do
438
+ |> Enum . reduce_while ( :ok , fn args , acc ->
439
+ case args |> SendCampaignEmail . new ( scheduled_at: args [ "scheduled_at" ] ) |> Oban . insert ( ) do
387
440
{ :ok , _ } -> { :cont , acc }
388
441
{ :error , _ } -> { :halt , :error }
389
442
end
0 commit comments