@@ -6,11 +6,13 @@ defmodule AlgoraWeb.Admin.CampaignLive do
66 import Ecto.Changeset
77 import Ecto.Query
88
9+ alias Algora.Accounts
910 alias Algora.Activities.Jobs.SendCampaignEmail
1011 alias Algora.Admin
1112 alias Algora.Mailer
1213 alias Algora.Repo
1314 alias Algora.Settings
15+ alias Algora.Util
1416 alias Algora.Workspace
1517 alias Algora.Workspace.Repository
1618 alias AlgoraWeb.LocalStore
@@ -45,11 +47,15 @@ defmodule AlgoraWeb.Admin.CampaignLive do
4547
4648 @ impl true
4749 def mount ( _params , _session , socket ) do
50+ timezone = if ( params = get_connect_params ( socket ) , do: params [ "timezone" ] )
51+
4852 { :ok ,
4953 socket
54+ |> assign ( :timezone , timezone )
5055 |> assign ( :page_title , "Campaign" )
5156 |> assign ( :form , to_form ( Campaign . changeset ( % Campaign { } ) ) )
5257 |> assign ( :repo_cache , % { } )
58+ |> assign ( :user_cache , % { } )
5359 |> assign_preview ( ) }
5460 end
5561
@@ -188,10 +194,12 @@ defmodule AlgoraWeb.Admin.CampaignLive do
188194 < . table id = "csv-data " rows = { @ csv_data } >
189195 <: col
190196 :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+ }
192200 label = { key }
193201 >
194- < . cell value = { row [ key ] } />
202+ < . cell value = { row [ key ] } timezone = { @ timezone } />
195203 </: col >
196204 <: action :let = { row } >
197205 < . button type = "button " phx-click = "send_email " phx-value-email = { row [ "email" ] } >
@@ -217,6 +225,17 @@ defmodule AlgoraWeb.Admin.CampaignLive do
217225 """
218226 end
219227
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+
220239 defp cell ( assigns ) do
221240 ~H"""
222241 < span class = "text-sm " >
@@ -229,7 +248,7 @@ defmodule AlgoraWeb.Admin.CampaignLive do
229248 Enum . reduce ( data , template , fn { key , value } , acc ->
230249 case value do
231250 value when is_list ( value ) -> acc
232- _ -> String . replace ( acc , "%{#{ key } }" , value )
251+ _ -> String . replace ( acc , "%{#{ key } }" , to_string ( value ) )
233252 end
234253 end )
235254 end
@@ -249,6 +268,39 @@ defmodule AlgoraWeb.Admin.CampaignLive do
249268
250269 defp repo_key ( _row ) , do: nil
251270
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+
252304 defp assign_repo_names ( socket ) do
253305 new_keys =
254306 socket . assigns . csv_data
@@ -342,6 +394,7 @@ defmodule AlgoraWeb.Admin.CampaignLive do
342394 socket
343395 |> assign ( :csv_data , csv_data )
344396 |> assign_repo_names ( )
397+ |> assign_timestamps ( )
345398 end
346399
347400 defp assign_preview ( socket ) do
@@ -374,16 +427,16 @@ defmodule AlgoraWeb.Admin.CampaignLive do
374427 id: Algora.Settings . get ( "email_campaign" ) [ "value" ] ,
375428 subject: subject ,
376429 recipient_email: recipient [ "email" ] ,
377- recipient: Algora. Util. term_to_base64 ( recipient ) ,
430+ recipient: Util . term_to_base64 ( recipient ) ,
378431 template: template ,
379432 from_name: from_name ,
380433 from_email: from_email ,
381- preheader: render_preview ( preheader , recipient )
434+ preheader: render_preview ( preheader , recipient ) ,
435+ scheduled_at: recipient [ "timestamp" ]
382436 }
383437 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
387440 { :ok , _ } -> { :cont , acc }
388441 { :error , _ } -> { :halt , :error }
389442 end
0 commit comments