From df0854ac399bae0e70624d12b7aadf5d2885eb23 Mon Sep 17 00:00:00 2001 From: Trevor Vallender Date: Wed, 29 May 2024 16:47:31 +0100 Subject: [PATCH] Email when invite is received --- app/controllers/table_invites_controller.rb | 5 +++++ app/controllers/tables_controller.rb | 1 + app/mailers/table_invite_mailer.rb | 11 ++++++++++ app/models/table_invite.rb | 2 ++ app/views/layouts/mailer.html.erb | 6 +++++- app/views/layouts/mailer.text.erb | 6 +++++- .../table_invite_mailer/invite_user.html.erb | 3 +++ .../table_invite_mailer/invite_user.text.erb | 3 +++ app/views/table_invites/index.html.erb | 11 ++++++++++ app/views/table_invites/new.html.erb | 2 +- app/views/tables/show.html.erb | 9 +++++++++ config/locales/en.yml | 14 +++++++++++-- config/routes.rb | 2 +- .../table_invites_controller_test.rb | 20 +++++++++++++++++++ todo.md | 6 ++++-- 15 files changed, 93 insertions(+), 8 deletions(-) create mode 100644 app/mailers/table_invite_mailer.rb create mode 100644 app/views/table_invite_mailer/invite_user.html.erb create mode 100644 app/views/table_invite_mailer/invite_user.text.erb create mode 100644 app/views/table_invites/index.html.erb diff --git a/app/controllers/table_invites_controller.rb b/app/controllers/table_invites_controller.rb index 1fb1fa3..19e45c2 100644 --- a/app/controllers/table_invites_controller.rb +++ b/app/controllers/table_invites_controller.rb @@ -4,6 +4,10 @@ class TableInvitesController < ApplicationController before_action :set_table, only: [ :new, :create ] before_action :set_table_invite, only: [ :edit, :update ] + def index + @table_invites = TableInvite.where(email: Current.user.email) + end + def new @table_invite = @table.table_invites.new end @@ -18,6 +22,7 @@ class TableInvitesController < ApplicationController @table_invite = @table.table_invites.new(table_invite_params) if @table_invite.save + TableInviteMailer.with(table_invite: @table_invite).invite_user.deliver_later redirect_to @table, notice: t(".success", email: @table_invite.email) else render :new, status: :unprocessable_entity, alert: t(".error") diff --git a/app/controllers/tables_controller.rb b/app/controllers/tables_controller.rb index c949277..4314603 100644 --- a/app/controllers/tables_controller.rb +++ b/app/controllers/tables_controller.rb @@ -8,6 +8,7 @@ class TablesController < ApplicationController end def show + @table_invites = @table.table_invites.not_responded end def new diff --git a/app/mailers/table_invite_mailer.rb b/app/mailers/table_invite_mailer.rb new file mode 100644 index 0000000..1b689ce --- /dev/null +++ b/app/mailers/table_invite_mailer.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +class TableInviteMailer < ApplicationMailer + helper(:mailer) + + def invite_user + @table_invite = params[:table_invite] + + mail(to: @table_invite.email, subject: "[Tabletop Companion] Invite to join a table") + end +end diff --git a/app/models/table_invite.rb b/app/models/table_invite.rb index 2a188c8..5ccd25b 100644 --- a/app/models/table_invite.rb +++ b/app/models/table_invite.rb @@ -7,6 +7,8 @@ class TableInvite < ApplicationRecord presence: true, length: { maximum: 100 } + scope :not_responded, -> { where(accepted_at: nil, declined_at: nil) } + def accepted? accepted_at.present? end diff --git a/app/views/layouts/mailer.html.erb b/app/views/layouts/mailer.html.erb index 533e85a..e994cab 100644 --- a/app/views/layouts/mailer.html.erb +++ b/app/views/layouts/mailer.html.erb @@ -8,7 +8,11 @@ -

<%= t(".greeting", name: @user.first_name) %>

+ <% if @user.present? %> +

<%= t(".greeting", name: @user.first_name) %>

+ <% else %> +

<%= t(".greeting_without_name") %>

+ <% end %> <%= yield %> <%= t(".sign_off_html") %> diff --git a/app/views/layouts/mailer.text.erb b/app/views/layouts/mailer.text.erb index 1c919c0..8c64e3e 100644 --- a/app/views/layouts/mailer.text.erb +++ b/app/views/layouts/mailer.text.erb @@ -1,4 +1,8 @@ -<%= t(".greeting") %> +<% if @user.present? %> + <%= t(".greeting", name: @user.first_name) %> +<% else %> + <%= t(".greeting_without_name") %> +<% end %> <%= yield %> diff --git a/app/views/table_invite_mailer/invite_user.html.erb b/app/views/table_invite_mailer/invite_user.html.erb new file mode 100644 index 0000000..adf0858 --- /dev/null +++ b/app/views/table_invite_mailer/invite_user.html.erb @@ -0,0 +1,3 @@ +<%= htmlify_email(t(".content", table_name: @table_invite.table.name)) %> + +<%= link_to t(".respond_to_invite"), table_invite_url(@table_invite) %> diff --git a/app/views/table_invite_mailer/invite_user.text.erb b/app/views/table_invite_mailer/invite_user.text.erb new file mode 100644 index 0000000..dfcc724 --- /dev/null +++ b/app/views/table_invite_mailer/invite_user.text.erb @@ -0,0 +1,3 @@ +<%= t(".content", table_name: @table_invite.table.name) %> + +<%= table_invite_url(@table_invite) %> diff --git a/app/views/table_invites/index.html.erb b/app/views/table_invites/index.html.erb new file mode 100644 index 0000000..a9c1b2d --- /dev/null +++ b/app/views/table_invites/index.html.erb @@ -0,0 +1,11 @@ +<% content_for :title, t(".table_invites") %> + +

<%= t(".table_invites") %>

+ +<% if @table_invites.any? %> + <% @table_invites.each do |table_invite| %> + <%= link_to table_invite.table, edit_table_invite_path(table_invite) %> + <% end %> +<% else %> +

<%= t(".no_table_invites") %>

+<% end %> diff --git a/app/views/table_invites/new.html.erb b/app/views/table_invites/new.html.erb index 360e10a..5cc1124 100644 --- a/app/views/table_invites/new.html.erb +++ b/app/views/table_invites/new.html.erb @@ -3,7 +3,7 @@

<%= t(".new_table_invite", name: @table.name) %>

<%= t(".new_invite_description") %>

-<%= form_with url: table_table_invites_path do |f| %> +<%= form_with model: @table_invite, url: table_table_invites_path do |f| %> <%= f.label :email %> <%= f.email_field :email %> diff --git a/app/views/tables/show.html.erb b/app/views/tables/show.html.erb index 27b1e24..6b188c8 100644 --- a/app/views/tables/show.html.erb +++ b/app/views/tables/show.html.erb @@ -11,3 +11,12 @@
<%= t(".owner") %>:
<%= @table.owner.username %>
+ +<% if @table_invites.any? %> +

Pending invites

+ +<% end %> diff --git a/config/locales/en.yml b/config/locales/en.yml index 4878263..343ca63 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -16,7 +16,8 @@ en: application: tables: Tables mailer: - greeting: "Hello, %{name}" + greeting: "Hi %{name}," + greeting_without_name: Hi, sign_off: | See you soon, The Tabletop Companion team @@ -60,7 +61,16 @@ en: destroy: log_out: Log out success: "You have signed out." + table_invite_mailer: + invite_user: + content: |- + You have been invited to join the table “%{table_name}” on Tabletop Companion. To + respond, visit the link below. + respond_to_invite: Respond to invite table_invites: + index: + table_invites: Your invitations + no_table_invites: You have no new invitations new: new_table_invite: Invite a player to %{name} new_invite_description: Enter an email address to invite a player to your table. @@ -68,7 +78,7 @@ en: button_text: Send invite create: user_not_found: There is no registered user with that email address. Ask them to sign up! - success: Send invite to %{email} + success: Sent invite to %{email} error: Failed to send invite edit: respond_to_invite: Respond to your invitation diff --git a/config/routes.rb b/config/routes.rb index 5025038..8c7e2a9 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -12,7 +12,7 @@ Rails.application.routes.draw do resources :account_verifications, only: [ :show ] resources :sessions, only: [ :new, :create, :destroy ] - resources :table_invites, only: [ :edit, :update ] + resources :table_invites, only: [ :index, :edit, :update ] resources :tables do resources :table_invites, only: [ :new, :create ] end diff --git a/test/controllers/table_invites_controller_test.rb b/test/controllers/table_invites_controller_test.rb index 03a179a..ca3da66 100644 --- a/test/controllers/table_invites_controller_test.rb +++ b/test/controllers/table_invites_controller_test.rb @@ -3,6 +3,12 @@ require "test_helper" class TableInviteInvitesControllerTest < ActionDispatch::IntegrationTest + test "should get index" do + sign_in users(:trevor) + get table_invites_url + assert_response :success + end + test "only a table owner can invite players" do sign_in users(:trevor) get new_table_table_invite_url(tables(:gimlis_table)) @@ -29,6 +35,20 @@ class TableInviteInvitesControllerTest < ActionDispatch::IntegrationTest assert_redirected_to table_path(tables(:table)) end + test "can’t invite a user who doesn’t exist" do + sign_in users(:trevor) + assert_no_changes("TableInvite.count") do + post(table_table_invites_url(tables(:table)), params: { table_invite: { email: "not_real@example.com" } }) + end + assert_response :unprocessable_entity + end + test "should email user when an invite is created" do + sign_in users(:trevor) + assert_emails(+1) do + post(table_table_invites_url(tables(:table)), params: { table_invite: { email: "uninvited_user@example.com" } }) + end + end + test "should accept table_invite" do sign_in users(:frodo) invite = table_invites(:unaccepted) diff --git a/todo.md b/todo.md index 018c317..5959998 100644 --- a/todo.md +++ b/todo.md @@ -1,4 +1,6 @@ -- Add players to tables -- notifications/table invites +- user page, avatar, profile description +- list invites on user page +- allow inviting non-users +- notifications - Add characters to users/tables - Character sheets/prototypes