From 459b9442bcee6cd18e8ee8b66c34980c929aa64d Mon Sep 17 00:00:00 2001 From: Douglas Berkley Date: Sun, 23 Jun 2024 15:25:09 +0900 Subject: [PATCH 01/11] Added job for predicitions missing --- app/jobs/notifications/prediction_missing_job.rb | 7 +++++++ test/jobs/notifications/prediction_missing_job_test.rb | 7 +++++++ 2 files changed, 14 insertions(+) create mode 100644 app/jobs/notifications/prediction_missing_job.rb create mode 100644 test/jobs/notifications/prediction_missing_job_test.rb diff --git a/app/jobs/notifications/prediction_missing_job.rb b/app/jobs/notifications/prediction_missing_job.rb new file mode 100644 index 0000000..b0d9204 --- /dev/null +++ b/app/jobs/notifications/prediction_missing_job.rb @@ -0,0 +1,7 @@ +class Notifications::PredictionMissingJob < ApplicationJob + queue_as :default + + def perform(*args) + # Do something later + end +end diff --git a/test/jobs/notifications/prediction_missing_job_test.rb b/test/jobs/notifications/prediction_missing_job_test.rb new file mode 100644 index 0000000..055f828 --- /dev/null +++ b/test/jobs/notifications/prediction_missing_job_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class Notifications::PredictionMissingJobTest < ActiveJob::TestCase + # test "the truth" do + # assert true + # end +end From e21bc5edc1ce4f396fe91731e99518a2e160cedd Mon Sep 17 00:00:00 2001 From: Douglas Berkley Date: Sun, 23 Jun 2024 15:55:47 +0900 Subject: [PATCH 02/11] added a notifications jsonb to users to set notication preferences --- app/models/user.rb | 20 +++++++++++++++++++ ...240623064544_add_notifications_to_users.rb | 15 ++++++++++++++ db/schema.rb | 5 ++++- 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20240623064544_add_notifications_to_users.rb diff --git a/app/models/user.rb b/app/models/user.rb index 79c214a..d9abc2b 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -22,6 +22,26 @@ def name super || email.split('@').first end + # user.notification_enabled?(:email, :prediction_missing) + # (query) User.where("notifications->'email'->>'prediction_missing' = ?", 'true') + def notification_enabled?(method, event) + notifications.dig(method.to_s, event.to_s) || false + end + + # user.enable_notification!(:email, :prediction_missing) + def enable_notification!(method, event) + self.notifications[method.to_s] ||= {} + self.notifications[method.to_s][event.to_s] = true + save + end + + # user.disable_notification!(:email, :prediction_missing) + def disable_notification!(method, event) + self.notifications[method.to_s] ||= {} + self.notifications[method.to_s][event.to_s] = false + save + end + private def auto_join_leaderboards diff --git a/db/migrate/20240623064544_add_notifications_to_users.rb b/db/migrate/20240623064544_add_notifications_to_users.rb new file mode 100644 index 0000000..c43e066 --- /dev/null +++ b/db/migrate/20240623064544_add_notifications_to_users.rb @@ -0,0 +1,15 @@ +class AddNotificationsToUsers < ActiveRecord::Migration[6.1] + def change + add_column :users, :notifications, :jsonb, default: {} + add_index :users, :notifications, using: :gin + User.find_each do |user| + user.notifications = { + email: { + prediction_missing: true, + competition_new: true + } + } + user.save + end + end +end diff --git a/db/schema.rb b/db/schema.rb index b86f751..16b19a1 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,9 +10,10 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2024_06_06_055739) do +ActiveRecord::Schema.define(version: 2024_06_23_064544) do # These are extensions that must be enabled in order to support this database + enable_extension "pg_stat_statements" enable_extension "plpgsql" create_table "active_storage_attachments", force: :cascade do |t| @@ -179,8 +180,10 @@ t.inet "current_sign_in_ip" t.inet "last_sign_in_ip" t.string "photo_key" + t.jsonb "notifications", default: {} t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true t.index ["email"], name: "index_users_on_email", unique: true + t.index ["notifications"], name: "index_users_on_notifications", using: :gin t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true t.index ["uid", "provider"], name: "index_users_on_uid_and_provider", unique: true end From 57bdf9a133d9bf35ebeb0587bf1ef6e3d04eb7b0 Mon Sep 17 00:00:00 2001 From: Douglas Berkley Date: Wed, 26 Jun 2024 15:36:43 +0900 Subject: [PATCH 03/11] created a mailer and job for the missing predictions --- app/jobs/email/prediction_missing_job.rb | 7 +++++++ app/jobs/notifications/prediction_missing_job.rb | 8 ++++++-- app/mailers/application_mailer.rb | 2 +- app/mailers/user_mailer.rb | 12 ++++++++++++ app/views/user_mailer/prediction_missing.html.erb | 5 +++++ app/views/user_mailer/prediction_missing.text.erb | 3 +++ test/jobs/email/prediction_missing_job_test.rb | 7 +++++++ test/mailers/previews/user_mailer_preview.rb | 9 +++++++++ test/mailers/user_mailer_test.rb | 12 ++++++++++++ 9 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 app/jobs/email/prediction_missing_job.rb create mode 100644 app/mailers/user_mailer.rb create mode 100644 app/views/user_mailer/prediction_missing.html.erb create mode 100644 app/views/user_mailer/prediction_missing.text.erb create mode 100644 test/jobs/email/prediction_missing_job_test.rb create mode 100644 test/mailers/previews/user_mailer_preview.rb create mode 100644 test/mailers/user_mailer_test.rb diff --git a/app/jobs/email/prediction_missing_job.rb b/app/jobs/email/prediction_missing_job.rb new file mode 100644 index 0000000..43b80f1 --- /dev/null +++ b/app/jobs/email/prediction_missing_job.rb @@ -0,0 +1,7 @@ +class Email::PredictionMissingJob < ApplicationJob + queue_as :default + + def perform(user_id, match_ids) + user = User.find(user_id) + end +end diff --git a/app/jobs/notifications/prediction_missing_job.rb b/app/jobs/notifications/prediction_missing_job.rb index b0d9204..1bf8cff 100644 --- a/app/jobs/notifications/prediction_missing_job.rb +++ b/app/jobs/notifications/prediction_missing_job.rb @@ -1,7 +1,11 @@ class Notifications::PredictionMissingJob < ApplicationJob queue_as :default - def perform(*args) - # Do something later + def perform(match_ids) + # email + users_to_email = User.where("notifications->'email'->>'prediction_missing' = ?", 'true') + users_to_email.each do |user| + Email::PredictionMissingJob.perform_later(user.id, match_ids) + end end end diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb index 286b223..d90f92a 100644 --- a/app/mailers/application_mailer.rb +++ b/app/mailers/application_mailer.rb @@ -1,4 +1,4 @@ class ApplicationMailer < ActionMailer::Base - default from: 'from@example.com' + default from: 'hello@octacle.app' layout 'mailer' end diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb new file mode 100644 index 0000000..6b9f343 --- /dev/null +++ b/app/mailers/user_mailer.rb @@ -0,0 +1,12 @@ +class UserMailer < ApplicationMailer + + # Subject can be set in your I18n file at config/locales/en.yml + # with the following lookup: + # + # en.user_mailer.prediction_missing.subject + # + def prediction_missing + @user = params[:user] # Instance variable => available in view + mail(to: @user.email, subject: "Octacle - Make your predictions before it's too late!") + end +end diff --git a/app/views/user_mailer/prediction_missing.html.erb b/app/views/user_mailer/prediction_missing.html.erb new file mode 100644 index 0000000..46dac8b --- /dev/null +++ b/app/views/user_mailer/prediction_missing.html.erb @@ -0,0 +1,5 @@ +

User#prediction_missing

+ +

+ <%= @greeting %>, find me in app/views/user_mailer/prediction_missing.html.erb +

diff --git a/app/views/user_mailer/prediction_missing.text.erb b/app/views/user_mailer/prediction_missing.text.erb new file mode 100644 index 0000000..57f3353 --- /dev/null +++ b/app/views/user_mailer/prediction_missing.text.erb @@ -0,0 +1,3 @@ +User#prediction_missing + +<%= @greeting %>, find me in app/views/user_mailer/prediction_missing.text.erb diff --git a/test/jobs/email/prediction_missing_job_test.rb b/test/jobs/email/prediction_missing_job_test.rb new file mode 100644 index 0000000..d03259f --- /dev/null +++ b/test/jobs/email/prediction_missing_job_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class Email::PredictionMissingJobTest < ActiveJob::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/mailers/previews/user_mailer_preview.rb b/test/mailers/previews/user_mailer_preview.rb new file mode 100644 index 0000000..f75545b --- /dev/null +++ b/test/mailers/previews/user_mailer_preview.rb @@ -0,0 +1,9 @@ +# Preview all emails at http://localhost:3000/rails/mailers/user_mailer +class UserMailerPreview < ActionMailer::Preview + + # Preview this email at http://localhost:3000/rails/mailers/user_mailer/prediction_missing + def prediction_missing + UserMailer.prediction_missing + end + +end diff --git a/test/mailers/user_mailer_test.rb b/test/mailers/user_mailer_test.rb new file mode 100644 index 0000000..174120a --- /dev/null +++ b/test/mailers/user_mailer_test.rb @@ -0,0 +1,12 @@ +require "test_helper" + +class UserMailerTest < ActionMailer::TestCase + test "prediction_missing" do + mail = UserMailer.prediction_missing + assert_equal "Prediction missing", mail.subject + assert_equal ["to@example.org"], mail.to + assert_equal ["from@example.com"], mail.from + assert_match "Hi", mail.body.encoded + end + +end From 1890b428b1251d23d37b54e0e542e8a0f90f66b7 Mon Sep 17 00:00:00 2001 From: Douglas Berkley Date: Thu, 27 Jun 2024 22:43:20 +0900 Subject: [PATCH 04/11] getting users who need to be notified --- app/jobs/notifications/prediction_missing_job.rb | 12 ++++++++---- app/mailers/user_mailer.rb | 3 +++ app/models/competition.rb | 13 ++++++++++++- app/models/user.rb | 13 +++++++++++++ 4 files changed, 36 insertions(+), 5 deletions(-) diff --git a/app/jobs/notifications/prediction_missing_job.rb b/app/jobs/notifications/prediction_missing_job.rb index 1bf8cff..35dec13 100644 --- a/app/jobs/notifications/prediction_missing_job.rb +++ b/app/jobs/notifications/prediction_missing_job.rb @@ -2,10 +2,14 @@ class Notifications::PredictionMissingJob < ApplicationJob queue_as :default def perform(match_ids) - # email - users_to_email = User.where("notifications->'email'->>'prediction_missing' = ?", 'true') - users_to_email.each do |user| - Email::PredictionMissingJob.perform_later(user.id, match_ids) + # load the matches + matches = Match.where(id: match_ids) + matches.each do |match| + users_to_email = User.need_prediction_notifications(match) + users_to_email.each do |user| + email = Email.find_by(user: user, match: match, notification: 'prediction_missing') + UserMailer.with(user: user, match: match).prediction_missing.deliver_later unless email + end end end end diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index 6b9f343..392ffa3 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -7,6 +7,9 @@ class UserMailer < ApplicationMailer # def prediction_missing @user = params[:user] # Instance variable => available in view + @match = params[:match] + @notification = params[:notification] mail(to: @user.email, subject: "Octacle - Make your predictions before it's too late!") + Email.create(user: @user, match: @match, notification: @notification) end end diff --git a/app/models/competition.rb b/app/models/competition.rb index 6032651..3261357 100644 --- a/app/models/competition.rb +++ b/app/models/competition.rb @@ -1,6 +1,6 @@ class Competition < ApplicationRecord belongs_to :current_round, class_name: 'Round', optional: true - has_many :matches, dependent: :destroy + has_many :matches, -> { distinct }, dependent: :destroy has_many :rounds, -> { distinct }, through: :matches has_many :groups, through: :rounds has_many :affiliations, through: :groups @@ -8,6 +8,8 @@ class Competition < ApplicationRecord has_many :leaderboards, dependent: :destroy has_many :predictions, through: :matches, dependent: :destroy has_many :users, through: :leaderboards, source: :users + # For some reason, this doesn't give me back a collection + # has_many :all_users_predicted, -> { distinct }, through: :predictions, source: :user has_one_attached :photo validates :name, presence: true, uniqueness: { scope: :start_date} @@ -26,4 +28,13 @@ def destroy_rounds def max_possible_score matches.finished.joins(:round).sum('rounds.points') end + + def users_predicted + # For some reason, this doesn't give me back a collection + # User.joins(:predictions) + # .where(predictions: { user_id: predictions.select(:user_id).distinct }).distinct + # TODO: refactor using an Active Record query that works + user_ids = User.find_by_sql(['SELECT DISTINCT users.id FROM users JOIN predictions ON predictions.user_id = users.id JOIN matches ON matches.id = predictions.match_id WHERE matches.competition_id = ?', id]) + User.where(id: user_ids.pluck(:id)) + end end diff --git a/app/models/user.rb b/app/models/user.rb index d9abc2b..258b6ca 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -14,6 +14,10 @@ class User < ApplicationRecord # Scenic views has_many :scores, class_name: 'UserScore' + scope :with_email_prediction_missing, -> { + where("notifications->'email'->>'prediction_missing' = ?", 'true') + } + validates :name, presence: true, on: :update, if: :name_changed? after_create :auto_join_leaderboards @@ -42,6 +46,15 @@ def disable_notification!(method, event) save end + def self.need_prediction_notifications(next_match) + return [] if next_match.blank? + + # total number of people who have made predicitons (and have email on) + users = next_match.competition.users_predicted.with_email_prediction_missing + # minus the ones who have made predictions for this match + users - users.joins(:predictions).where(predictions: { match_id: next_match.id }) + end + private def auto_join_leaderboards From 59f75ea62b1d82e00e44d8072ecf91c63fbc9600 Mon Sep 17 00:00:00 2001 From: Douglas Berkley Date: Fri, 28 Jun 2024 00:05:18 +0900 Subject: [PATCH 05/11] Added email model --- app/jobs/email/prediction_missing_job.rb | 7 ------ .../notifications/prediction_missing_job.rb | 2 +- app/mailers/user_mailer.rb | 4 ++-- app/models/email.rb | 4 ++++ app/models/user.rb | 1 + .../user_mailer/prediction_missing.html.erb | 22 +++++++++++++++---- db/migrate/20240627134655_create_emails.rb | 10 +++++++++ db/schema.rb | 14 +++++++++++- test/fixtures/emails.yml | 11 ++++++++++ .../jobs/email/prediction_missing_job_test.rb | 2 +- test/models/email_test.rb | 7 ++++++ 11 files changed, 68 insertions(+), 16 deletions(-) delete mode 100644 app/jobs/email/prediction_missing_job.rb create mode 100644 app/models/email.rb create mode 100644 db/migrate/20240627134655_create_emails.rb create mode 100644 test/fixtures/emails.yml create mode 100644 test/models/email_test.rb diff --git a/app/jobs/email/prediction_missing_job.rb b/app/jobs/email/prediction_missing_job.rb deleted file mode 100644 index 43b80f1..0000000 --- a/app/jobs/email/prediction_missing_job.rb +++ /dev/null @@ -1,7 +0,0 @@ -class Email::PredictionMissingJob < ApplicationJob - queue_as :default - - def perform(user_id, match_ids) - user = User.find(user_id) - end -end diff --git a/app/jobs/notifications/prediction_missing_job.rb b/app/jobs/notifications/prediction_missing_job.rb index 35dec13..15e8653 100644 --- a/app/jobs/notifications/prediction_missing_job.rb +++ b/app/jobs/notifications/prediction_missing_job.rb @@ -7,7 +7,7 @@ def perform(match_ids) matches.each do |match| users_to_email = User.need_prediction_notifications(match) users_to_email.each do |user| - email = Email.find_by(user: user, match: match, notification: 'prediction_missing') + email = Email.find_by(user: user, topic: match, notification: 'prediction_missing') UserMailer.with(user: user, match: match).prediction_missing.deliver_later unless email end end diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index 392ffa3..294f814 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -9,7 +9,7 @@ def prediction_missing @user = params[:user] # Instance variable => available in view @match = params[:match] @notification = params[:notification] - mail(to: @user.email, subject: "Octacle - Make your predictions before it's too late!") - Email.create(user: @user, match: @match, notification: @notification) + mail(to: @user.email, subject: "Octacle - You're missing a prediction for #{@match.team_home.abbrev} vs. #{@match.team_away.abbrev}") + Email.create(user: @user, topic: @match, notification: @notification) end end diff --git a/app/models/email.rb b/app/models/email.rb new file mode 100644 index 0000000..f1eb3e4 --- /dev/null +++ b/app/models/email.rb @@ -0,0 +1,4 @@ +class Email < ApplicationRecord + belongs_to :user + belongs_to :topic, polymorphic: true, optional: true +end diff --git a/app/models/user.rb b/app/models/user.rb index 258b6ca..7333c3c 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -10,6 +10,7 @@ class User < ApplicationRecord # has_many :competitions, through: :leaderboards has_many :predictions, dependent: :destroy has_many :matches, through: :predictions + has_many :emails, dependent: :destroy # Scenic views has_many :scores, class_name: 'UserScore' diff --git a/app/views/user_mailer/prediction_missing.html.erb b/app/views/user_mailer/prediction_missing.html.erb index 46dac8b..72725a1 100644 --- a/app/views/user_mailer/prediction_missing.html.erb +++ b/app/views/user_mailer/prediction_missing.html.erb @@ -1,5 +1,19 @@ -

User#prediction_missing

+ +
+

Make your prediction before it's too late!

+

<%= @match.team_home.abbrev %> vs. <%= @match.team_away.abbrev %> kicks off at <%= @match.kickoff_time.strftime('%a, %e %b %H:%M') %> UTC

+

+ <%= link_to 'Visit Octacle to Choose', 'https://www.octacle.app/competitions/predictions', class: 'btn', target: '_blank' %> +

+
diff --git a/db/migrate/20240627134655_create_emails.rb b/db/migrate/20240627134655_create_emails.rb new file mode 100644 index 0000000..109258f --- /dev/null +++ b/db/migrate/20240627134655_create_emails.rb @@ -0,0 +1,10 @@ +class CreateEmails < ActiveRecord::Migration[6.1] + def change + create_table :emails do |t| + t.references :user, null: false, foreign_key: true + t.string :notification + t.references :topic, polymorphic: true + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 16b19a1..6f59ecd 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2024_06_23_064544) do +ActiveRecord::Schema.define(version: 2024_06_27_134655) do # These are extensions that must be enabled in order to support this database enable_extension "pg_stat_statements" @@ -65,6 +65,17 @@ t.index ["current_round_id"], name: "index_competitions_on_current_round_id" end + create_table "emails", force: :cascade do |t| + t.bigint "user_id", null: false + t.string "notification" + t.string "topic_type" + t.bigint "topic_id" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["topic_type", "topic_id"], name: "index_emails_on_topic" + t.index ["user_id"], name: "index_emails_on_user_id" + end + create_table "groups", force: :cascade do |t| t.string "name" t.bigint "round_id", null: false @@ -193,6 +204,7 @@ add_foreign_key "affiliations", "groups" add_foreign_key "affiliations", "teams" add_foreign_key "competitions", "rounds", column: "current_round_id" + add_foreign_key "emails", "users" add_foreign_key "groups", "rounds" add_foreign_key "leaderboards", "competitions" add_foreign_key "leaderboards", "users" diff --git a/test/fixtures/emails.yml b/test/fixtures/emails.yml new file mode 100644 index 0000000..d45d6f3 --- /dev/null +++ b/test/fixtures/emails.yml @@ -0,0 +1,11 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + user: one + notification: 1 + topic: one + +two: + user: two + notification: 1 + topic: two diff --git a/test/jobs/email/prediction_missing_job_test.rb b/test/jobs/email/prediction_missing_job_test.rb index d03259f..f6a5ac1 100644 --- a/test/jobs/email/prediction_missing_job_test.rb +++ b/test/jobs/email/prediction_missing_job_test.rb @@ -1,6 +1,6 @@ require "test_helper" -class Email::PredictionMissingJobTest < ActiveJob::TestCase +class Emails::PredictionMissingJobTest < ActiveJob::TestCase # test "the truth" do # assert true # end diff --git a/test/models/email_test.rb b/test/models/email_test.rb new file mode 100644 index 0000000..a07b515 --- /dev/null +++ b/test/models/email_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class EmailTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end From 99afbddb7b941e39adc7b6cc23e8e34e10b790ab Mon Sep 17 00:00:00 2001 From: Douglas Berkley Date: Fri, 28 Jun 2024 00:08:53 +0900 Subject: [PATCH 06/11] passed extra argument to email --- app/jobs/notifications/prediction_missing_job.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/jobs/notifications/prediction_missing_job.rb b/app/jobs/notifications/prediction_missing_job.rb index 15e8653..8767105 100644 --- a/app/jobs/notifications/prediction_missing_job.rb +++ b/app/jobs/notifications/prediction_missing_job.rb @@ -8,7 +8,7 @@ def perform(match_ids) users_to_email = User.need_prediction_notifications(match) users_to_email.each do |user| email = Email.find_by(user: user, topic: match, notification: 'prediction_missing') - UserMailer.with(user: user, match: match).prediction_missing.deliver_later unless email + UserMailer.with(user: user, match: match, notification: 'prediction_missing').prediction_missing.deliver_later unless email end end end From 73b27ff302f398947c0599b1f1cf7e623481b505 Mon Sep 17 00:00:00 2001 From: Douglas Berkley Date: Sat, 29 Jun 2024 16:07:02 +0900 Subject: [PATCH 07/11] added style to email --- app/views/layouts/mailer.html.erb | 16 ++++++++-- app/views/shared/_banner.html.erb | 4 +++ .../user_mailer/prediction_missing.html.erb | 30 ++++++++----------- 3 files changed, 31 insertions(+), 19 deletions(-) create mode 100644 app/views/shared/_banner.html.erb diff --git a/app/views/layouts/mailer.html.erb b/app/views/layouts/mailer.html.erb index cbd34d2..42c64f6 100644 --- a/app/views/layouts/mailer.html.erb +++ b/app/views/layouts/mailer.html.erb @@ -2,11 +2,23 @@ + - <%= yield %> diff --git a/app/views/shared/_banner.html.erb b/app/views/shared/_banner.html.erb new file mode 100644 index 0000000..077f518 --- /dev/null +++ b/app/views/shared/_banner.html.erb @@ -0,0 +1,4 @@ +
+ <%= image_tag 'https://raw.githubusercontent.com/trouni/predictor-vue/main/src/assets/logo.png', width: 100, alt: "text", class: 'me-2' %> +

Octacle

+
diff --git a/app/views/user_mailer/prediction_missing.html.erb b/app/views/user_mailer/prediction_missing.html.erb index 72725a1..58ff7dc 100644 --- a/app/views/user_mailer/prediction_missing.html.erb +++ b/app/views/user_mailer/prediction_missing.html.erb @@ -1,19 +1,15 @@ -
-

Make your prediction before it's too late!

-

<%= @match.team_home.abbrev %> vs. <%= @match.team_away.abbrev %> kicks off at <%= @match.kickoff_time.strftime('%a, %e %b %H:%M') %> UTC

-

- <%= link_to 'Visit Octacle to Choose', 'https://www.octacle.app/competitions/predictions', class: 'btn', target: '_blank' %> -

+ <%= render 'shared/banner' %> +
+
+
+ <%= image_tag cl_image_path(@match.team_home.flag.key), alt: "text", width: 100, class: 'me-2 rounded' %><%= @match.team_home.name %> vs. <%= @match.team_away.name %> <%= image_tag cl_image_path(@match.team_away.flag.key), alt: "text", width: 100, class: 'ms-2 rounded' %> +
+

The match kicks off at <%= @match.kickoff_time.strftime('%a, %e %b %H:%M') %> UTC.

+

Don't forget to get your prediction locked in!

+

+ <%= link_to 'Visit Octacle', 'https://www.octacle.app/competitions/predictions', class: 'btn btn-purple', target: '_blank' %> +

+
+
From bb80ae327d30c10a22b803f607a8386a6f335675 Mon Sep 17 00:00:00 2001 From: Douglas Berkley Date: Sat, 29 Jun 2024 16:23:27 +0900 Subject: [PATCH 08/11] Added unsubsrcibe button --- app/views/shared/_unsubscribe.html.erb | 1 + app/views/user_mailer/prediction_missing.html.erb | 3 +++ 2 files changed, 4 insertions(+) create mode 100644 app/views/shared/_unsubscribe.html.erb diff --git a/app/views/shared/_unsubscribe.html.erb b/app/views/shared/_unsubscribe.html.erb new file mode 100644 index 0000000..3ac0bba --- /dev/null +++ b/app/views/shared/_unsubscribe.html.erb @@ -0,0 +1 @@ +<%= link_to 'Unsubscribe', 'https://www.octacle.app/profile', class: 'text-muted text-decoration-none' %> diff --git a/app/views/user_mailer/prediction_missing.html.erb b/app/views/user_mailer/prediction_missing.html.erb index 58ff7dc..34b376a 100644 --- a/app/views/user_mailer/prediction_missing.html.erb +++ b/app/views/user_mailer/prediction_missing.html.erb @@ -10,6 +10,9 @@

<%= link_to 'Visit Octacle', 'https://www.octacle.app/competitions/predictions', class: 'btn btn-purple', target: '_blank' %>

+

+ <%= render 'shared/unsubscribe' %> +

From 3c65806c6ba0147171e5153c7201bede834d2360 Mon Sep 17 00:00:00 2001 From: Douglas Berkley Date: Sat, 29 Jun 2024 16:30:57 +0900 Subject: [PATCH 09/11] added notifications to the daily tasks --- app/jobs/notifications/prediction_missing_job.rb | 3 ++- app/jobs/schedule_daily_tasks_job.rb | 4 ++++ app/views/v1/users/_user.json.jbuilder | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/app/jobs/notifications/prediction_missing_job.rb b/app/jobs/notifications/prediction_missing_job.rb index 8767105..eef7c0f 100644 --- a/app/jobs/notifications/prediction_missing_job.rb +++ b/app/jobs/notifications/prediction_missing_job.rb @@ -2,11 +2,12 @@ class Notifications::PredictionMissingJob < ApplicationJob queue_as :default def perform(match_ids) - # load the matches matches = Match.where(id: match_ids) matches.each do |match| + # loads all users in this competition that have emailing turned on users_to_email = User.need_prediction_notifications(match) users_to_email.each do |user| + # Checks to see if an email has already been sent email = Email.find_by(user: user, topic: match, notification: 'prediction_missing') UserMailer.with(user: user, match: match, notification: 'prediction_missing').prediction_missing.deliver_later unless email end diff --git a/app/jobs/schedule_daily_tasks_job.rb b/app/jobs/schedule_daily_tasks_job.rb index 3df356f..1785960 100644 --- a/app/jobs/schedule_daily_tasks_job.rb +++ b/app/jobs/schedule_daily_tasks_job.rb @@ -4,10 +4,14 @@ class ScheduleDailyTasksJob < ApplicationJob def perform competitions = Competition.on_going competitions.each do |competition| + # Schedules the matches as "started" based on their kickoff_time matches = competition.matches.where(kickoff_time: Date.today.all_day) matches.pluck(:kickoff_time).uniq.each do |kickoff_time| MatchStartedJob.set(wait_until: kickoff_time).perform_later(kickoff_time) end + # Schedules notifications for missing predicitions + matches_tomorrow = competition.matches.where(kickoff_time: Date.tomorrow.all_day) + Notifications::PredictionMissingJob.perform_later(matches_tomorrow.pluck(:id)) end end end diff --git a/app/views/v1/users/_user.json.jbuilder b/app/views/v1/users/_user.json.jbuilder index fcb41bd..a7ecd82 100644 --- a/app/views/v1/users/_user.json.jbuilder +++ b/app/views/v1/users/_user.json.jbuilder @@ -1 +1 @@ -json.extract! user, :id, :email, :timezone, :admin, :photo_key, :name +json.extract! user, :id, :email, :timezone, :admin, :photo_key, :name, :notifications From de083b42dfe4123eea834a9d55773d0f2a59378e Mon Sep 17 00:00:00 2001 From: Douglas Berkley Date: Sat, 29 Jun 2024 16:45:24 +0900 Subject: [PATCH 10/11] added font to banner and added preferences in user strong params --- app/controllers/v1/users_controller.rb | 2 +- app/views/layouts/mailer.html.erb | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/controllers/v1/users_controller.rb b/app/controllers/v1/users_controller.rb index c759abf..6646d57 100644 --- a/app/controllers/v1/users_controller.rb +++ b/app/controllers/v1/users_controller.rb @@ -21,6 +21,6 @@ def update private def prediction_params - params.require(:user).permit(:name, :timezone, :photo_key) + params.require(:user).permit(:name, :timezone, :photo_key, preferences: {}) end end diff --git a/app/views/layouts/mailer.html.erb b/app/views/layouts/mailer.html.erb index 42c64f6..afa23db 100644 --- a/app/views/layouts/mailer.html.erb +++ b/app/views/layouts/mailer.html.erb @@ -4,6 +4,10 @@