@@ -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
@@ -191,7 +197,7 @@ defmodule AlgoraWeb.Admin.CampaignLive do
191
197
:for = { key <- @ csv_columns |> Enum . filter ( & ( & 1 != "repo_url" ) ) }
192
198
label = { key }
193
199
>
194
- < . cell value = { row [ key ] } />
200
+ < . cell value = { row [ key ] } timezone = { @ timezone } />
195
201
</: col >
196
202
<: action :let = { row } >
197
203
< . button type = "button " phx-click = "send_email " phx-value-email = { row [ "email" ] } >
@@ -217,6 +223,17 @@ defmodule AlgoraWeb.Admin.CampaignLive do
217
223
"""
218
224
end
219
225
226
+ defp cell ( % { value: % DateTime { } } = assigns ) do
227
+ ~H"""
228
+ < span :if = { @ timezone } class = "tabular-nums whitespace-nowrap text-sm " >
229
+ { Calendar . strftime (
230
+ DateTime . from_naive! ( @ value , "Etc/UTC" ) |> DateTime . shift_zone! ( @ timezone ) ,
231
+ "%Y/%m/%d, %H:%M:%S"
232
+ ) }
233
+ </ span >
234
+ """
235
+ end
236
+
220
237
defp cell ( assigns ) do
221
238
~H"""
222
239
< span class = "text-sm " >
@@ -229,7 +246,7 @@ defmodule AlgoraWeb.Admin.CampaignLive do
229
246
Enum . reduce ( data , template , fn { key , value } , acc ->
230
247
case value do
231
248
value when is_list ( value ) -> acc
232
- _ -> String . replace ( acc , "%{#{ key } }" , value )
249
+ _ -> String . replace ( acc , "%{#{ key } }" , to_string ( value ) )
233
250
end
234
251
end )
235
252
end
@@ -249,6 +266,39 @@ defmodule AlgoraWeb.Admin.CampaignLive do
249
266
250
267
defp repo_key ( _row ) , do: nil
251
268
269
+ defp assign_timestamps ( socket ) do
270
+ new_keys =
271
+ socket . assigns . csv_data
272
+ |> Enum . map ( & Map . get ( & 1 , "email" ) )
273
+ |> Enum . uniq ( )
274
+
275
+ new_cache =
276
+ Map . new ( new_keys , fn key ->
277
+ user = Accounts . get_user_by_email ( key )
278
+
279
+ if user do
280
+ { key , Util . next_occurrence_of_time ( user . last_active_at || user . inserted_at ) }
281
+ else
282
+ { key , Util . next_occurrence_of_time ( Util . random_datetime ( ) ) }
283
+ end
284
+ end )
285
+
286
+ updated_cache = Map . merge ( socket . assigns . user_cache , new_cache )
287
+
288
+ csv_data =
289
+ Enum . map ( socket . assigns . csv_data , fn row -> Map . put ( row , "timestamp" , Map . get ( updated_cache , row [ "email" ] ) ) end )
290
+
291
+ csv_columns =
292
+ csv_data
293
+ |> Enum . flat_map ( & Map . keys / 1 )
294
+ |> Enum . uniq ( )
295
+
296
+ socket
297
+ |> assign ( :repo_cache , updated_cache )
298
+ |> assign ( :csv_data , csv_data )
299
+ |> assign ( :csv_columns , csv_columns )
300
+ end
301
+
252
302
defp assign_repo_names ( socket ) do
253
303
new_keys =
254
304
socket . assigns . csv_data
@@ -342,6 +392,7 @@ defmodule AlgoraWeb.Admin.CampaignLive do
342
392
socket
343
393
|> assign ( :csv_data , csv_data )
344
394
|> assign_repo_names ( )
395
+ |> assign_timestamps ( )
345
396
end
346
397
347
398
defp assign_preview ( socket ) do
@@ -374,16 +425,16 @@ defmodule AlgoraWeb.Admin.CampaignLive do
374
425
id: Algora.Settings . get ( "email_campaign" ) [ "value" ] ,
375
426
subject: subject ,
376
427
recipient_email: recipient [ "email" ] ,
377
- recipient: Algora. Util. term_to_base64 ( recipient ) ,
428
+ recipient: Util . term_to_base64 ( recipient ) ,
378
429
template: template ,
379
430
from_name: from_name ,
380
431
from_email: from_email ,
381
- preheader: render_preview ( preheader , recipient )
432
+ preheader: render_preview ( preheader , recipient ) ,
433
+ scheduled_at: recipient [ "timestamp" ]
382
434
}
383
435
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
436
+ |> Enum . reduce_while ( :ok , fn args , acc ->
437
+ case args |> SendCampaignEmail . new ( scheduled_at: args [ :scheduled_at ] ) |> Oban . insert ( ) do
387
438
{ :ok , _ } -> { :cont , acc }
388
439
{ :error , _ } -> { :halt , :error }
389
440
end
0 commit comments