Email when invite is received

This commit is contained in:
Trevor Vallender 2024-05-29 16:47:31 +01:00
parent 18c264b64b
commit df0854ac39
15 changed files with 93 additions and 8 deletions

View File

@ -4,6 +4,10 @@ class TableInvitesController < ApplicationController
before_action :set_table, only: [ :new, :create ] before_action :set_table, only: [ :new, :create ]
before_action :set_table_invite, only: [ :edit, :update ] before_action :set_table_invite, only: [ :edit, :update ]
def index
@table_invites = TableInvite.where(email: Current.user.email)
end
def new def new
@table_invite = @table.table_invites.new @table_invite = @table.table_invites.new
end end
@ -18,6 +22,7 @@ class TableInvitesController < ApplicationController
@table_invite = @table.table_invites.new(table_invite_params) @table_invite = @table.table_invites.new(table_invite_params)
if @table_invite.save if @table_invite.save
TableInviteMailer.with(table_invite: @table_invite).invite_user.deliver_later
redirect_to @table, notice: t(".success", email: @table_invite.email) redirect_to @table, notice: t(".success", email: @table_invite.email)
else else
render :new, status: :unprocessable_entity, alert: t(".error") render :new, status: :unprocessable_entity, alert: t(".error")

View File

@ -8,6 +8,7 @@ class TablesController < ApplicationController
end end
def show def show
@table_invites = @table.table_invites.not_responded
end end
def new def new

View File

@ -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

View File

@ -7,6 +7,8 @@ class TableInvite < ApplicationRecord
presence: true, presence: true,
length: { maximum: 100 } length: { maximum: 100 }
scope :not_responded, -> { where(accepted_at: nil, declined_at: nil) }
def accepted? def accepted?
accepted_at.present? accepted_at.present?
end end

View File

@ -8,7 +8,11 @@
</head> </head>
<body> <body>
<% if @user.present? %>
<p><%= t(".greeting", name: @user.first_name) %></p> <p><%= t(".greeting", name: @user.first_name) %></p>
<% else %>
<p><%= t(".greeting_without_name") %></p>
<% end %>
<%= yield %> <%= yield %>
<%= t(".sign_off_html") %> <%= t(".sign_off_html") %>
</body> </body>

View File

@ -1,4 +1,8 @@
<%= t(".greeting") %> <% if @user.present? %>
<%= t(".greeting", name: @user.first_name) %>
<% else %>
<%= t(".greeting_without_name") %>
<% end %>
<%= yield %> <%= yield %>

View File

@ -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) %>

View File

@ -0,0 +1,3 @@
<%= t(".content", table_name: @table_invite.table.name) %>
<%= table_invite_url(@table_invite) %>

View File

@ -0,0 +1,11 @@
<% content_for :title, t(".table_invites") %>
<h2><%= t(".table_invites") %></h2>
<% if @table_invites.any? %>
<% @table_invites.each do |table_invite| %>
<%= link_to table_invite.table, edit_table_invite_path(table_invite) %>
<% end %>
<% else %>
<p><%= t(".no_table_invites") %></p>
<% end %>

View File

@ -3,7 +3,7 @@
<h2><%= t(".new_table_invite", name: @table.name) %></h2> <h2><%= t(".new_table_invite", name: @table.name) %></h2>
<p><%= t(".new_invite_description") %></p> <p><%= t(".new_invite_description") %></p>
<%= 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.label :email %>
<%= f.email_field :email %> <%= f.email_field :email %>

View File

@ -11,3 +11,12 @@
<dt><%= t(".owner") %>:</dt> <dt><%= t(".owner") %>:</dt>
<dd><%= @table.owner.username %></dd> <dd><%= @table.owner.username %></dd>
</dl> </dl>
<% if @table_invites.any? %>
<h4>Pending invites</h4>
<ul>
<% @table_invites.each do |table_invite| %>
<li><%= table_invite.email %></li>
<% end %>
</ul>
<% end %>

View File

@ -16,7 +16,8 @@ en:
application: application:
tables: Tables tables: Tables
mailer: mailer:
greeting: "Hello, %{name}" greeting: "Hi %{name},"
greeting_without_name: Hi,
sign_off: | sign_off: |
See you soon, See you soon,
The Tabletop Companion team The Tabletop Companion team
@ -60,7 +61,16 @@ en:
destroy: destroy:
log_out: Log out log_out: Log out
success: "You have signed 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: table_invites:
index:
table_invites: Your invitations
no_table_invites: You have no new invitations
new: new:
new_table_invite: Invite a player to %{name} new_table_invite: Invite a player to %{name}
new_invite_description: Enter an email address to invite a player to your table. new_invite_description: Enter an email address to invite a player to your table.
@ -68,7 +78,7 @@ en:
button_text: Send invite button_text: Send invite
create: create:
user_not_found: There is no registered user with that email address. Ask them to sign up! 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 error: Failed to send invite
edit: edit:
respond_to_invite: Respond to your invitation respond_to_invite: Respond to your invitation

View File

@ -12,7 +12,7 @@ Rails.application.routes.draw do
resources :account_verifications, only: [ :show ] resources :account_verifications, only: [ :show ]
resources :sessions, only: [ :new, :create, :destroy ] resources :sessions, only: [ :new, :create, :destroy ]
resources :table_invites, only: [ :edit, :update ] resources :table_invites, only: [ :index, :edit, :update ]
resources :tables do resources :tables do
resources :table_invites, only: [ :new, :create ] resources :table_invites, only: [ :new, :create ]
end end

View File

@ -3,6 +3,12 @@
require "test_helper" require "test_helper"
class TableInviteInvitesControllerTest < ActionDispatch::IntegrationTest 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 test "only a table owner can invite players" do
sign_in users(:trevor) sign_in users(:trevor)
get new_table_table_invite_url(tables(:gimlis_table)) get new_table_table_invite_url(tables(:gimlis_table))
@ -29,6 +35,20 @@ class TableInviteInvitesControllerTest < ActionDispatch::IntegrationTest
assert_redirected_to table_path(tables(:table)) assert_redirected_to table_path(tables(:table))
end end
test "cant invite a user who doesnt 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 test "should accept table_invite" do
sign_in users(:frodo) sign_in users(:frodo)
invite = table_invites(:unaccepted) invite = table_invites(:unaccepted)

View File

@ -1,4 +1,6 @@
- Add players to tables - user page, avatar, profile description
- notifications/table invites - list invites on user page
- allow inviting non-users
- notifications
- Add characters to users/tables - Add characters to users/tables
- Character sheets/prototypes - Character sheets/prototypes