diff --git a/app/controllers/invite_requests_controller.rb b/app/controllers/invite_requests_controller.rb index a8c3f78e1e5..95c981dbdd8 100644 --- a/app/controllers/invite_requests_controller.rb +++ b/app/controllers/invite_requests_controller.rb @@ -27,8 +27,8 @@ def resend if @invitation.nil? flash[:error] = ts("Could not find an invitation associated with that email.") - elsif @invitation.sent_at < ArchiveConfig.HOURS_BEFORE_RESEND_INVITATION.hours.ago - @invitation.send_and_set_date + elsif @invitation.can_resend? + @invitation.send_and_set_date(resend: true) flash[:notice] = ts("Invitation resent to %{email}.", email: @invitation.invitee_email) else flash[:error] = ts("You cannot resend an invitation that was sent in the last %{count} hours.", diff --git a/app/models/invitation.rb b/app/models/invitation.rb index 04056810a25..e35a5d8fa25 100644 --- a/app/models/invitation.rb +++ b/app/models/invitation.rb @@ -55,7 +55,7 @@ def mark_as_redeemed(user=nil) save end - def send_and_set_date + def send_and_set_date(resend: false) return if invitee_email.blank? begin @@ -68,13 +68,19 @@ def send_and_set_date UserMailer.invitation(self.id).deliver_now end + date_column = resend ? :resent_at : :sent_at # Skip callbacks within after_save by using update_column to avoid a callback loop - self.update_column(:sent_at, Time.now) + self.update_column(date_column, Time.now) rescue Exception => exception errors.add(:base, "Notification email could not be sent: #{exception.message}") end end + def can_resend? + checked_date = self.resent_at ? self.resent_at : self.sent_at + checked_date < ArchiveConfig.HOURS_BEFORE_RESEND_INVITATION.hours.ago + end + private def generate_token diff --git a/app/views/invitations/_invitation.html.erb b/app/views/invitations/_invitation.html.erb index f2cefdfb5c9..ae915164f10 100644 --- a/app/views/invitations/_invitation.html.erb +++ b/app/views/invitations/_invitation.html.erb @@ -24,6 +24,8 @@
<%= invitation.created_at %>
Sent at
<%= invitation.sent_at %>
+
Resent at
+
<%= invitation.resent_at %>
Redeemed at
<%= invitation.redeemed_at %>
diff --git a/app/views/invite_requests/_invitation.html.erb b/app/views/invite_requests/_invitation.html.erb index 62069367c6a..3ee0bea67e2 100644 --- a/app/views/invite_requests/_invitation.html.erb +++ b/app/views/invite_requests/_invitation.html.erb @@ -1,15 +1,34 @@ -

+

<%= t(".title", email: invitation.invitee_email) %>

+<% status = invitation.resent_at ? "resent" : "not_resent" %>

-<%= t(".date", date: l(invitation.sent_at.to_date)) %> -<% if invitation.sent_at < ArchiveConfig.HOURS_BEFORE_RESEND_INVITATION.hours.ago %> - <%= t(".resend", count: ArchiveConfig.HOURS_BEFORE_RESEND_INVITATION) %> - <%= button_to t(".resend_button"), resend_invite_requests_path(email: invitation.invitee_email) %> -<% end %> + <%= t(".info.#{status}", + sent_at: l(invitation.sent_at.to_date), + resent_at: invitation.resent_at ? l(invitation.resent_at.to_date) : nil ) %> + <% if invitation.can_resend? %> + <%# i18n-tasks-use t("invite_requests.invitation.after_cooldown_period.not_resent") + i18n-tasks-use t("invite_requests.invitation.after_cooldown_period.resent")-%> + <%= t(".after_cooldown_period.#{status}", + count: ArchiveConfig.HOURS_BEFORE_RESEND_INVITATION, + support_link: link_to(t(".contact_support"), new_feedback_report_path)) %> + <%= button_to t(".resend_button"), resend_invite_requests_path(email: invitation.invitee_email) %> + <% else %> + <%= t(".before_cooldown_period", count: ArchiveConfig.HOURS_BEFORE_RESEND_INVITATION) %> + <% end %>

+ +<%= content_for :footer_js do %> + <%= javascript_tag do %> + $j(document).ready(function(){ + $j('#invite-heading').replaceWith(function () { + return "

" + $j(this).html() + "

"; + }); + }) + <% end %> +<% end %> diff --git a/config/locales/views/en.yml b/config/locales/views/en.yml index 0e080ff4828..d36444f1055 100644 --- a/config/locales/views/en.yml +++ b/config/locales/views/en.yml @@ -483,17 +483,27 @@ en: invitation: email_address_label: Enter an email address invite_requests: + invitation: + after_cooldown_period: + not_resent: + one: Because your invitation was sent more than an hour ago, you can have your invitation resent. + other: Because your invitation was sent more than %{count} hours ago, you can have your invitation resent. + resent: + one: Because your invitation was resent more than an hour ago, you can have your invitation resent again, or you may want to %{support_link}. + other: Because your invitation was resent more than %{count} hours ago, you can have your invitation resent again, or you may want to %{support_link}. + before_cooldown_period: + one: if it has been more than an hour since you should have received your invitation, but you have not received it after checking your spam folder, you can visit this page to resend the invitation. + other: if it has been more than %{count} hours since you should have received your invitation, but you have not received it after checking your spam folder, you can visit this page to resend the invitation. + contact_support: contact Support + info: + not_resent: Your invitation was emailed to this address on %{sent_at}. If you can't find it, please check your email spam folder as your spam filters may have placed it there. + resent: Your invitation was emailed to this address on %{sent_at} and resent on %{resent_at}. If you can't find it, please check your email spam folder as your spam filters may have placed it there. + resend_button: Resend Invitation + title: Invitation Status for %{email} invite_request: date: 'At our current rate, you should receive an invitation on or around: %{date}.' position_html: You are currently number %{position} on our waiting list! title: Invitation Status for %{email} - invitation: - title: Invitation Status for %{email} - date: Your invitation was emailed to this address on %{date}. If you can't find it, please check your email spam folder as your spam filters may have placed it there. - resend: - one: Because your invitation was sent more than an hour ago, you can have your invitation resent. - other: Because your invitation was sent more than %{count} hours ago, you can have your invitation resent. - resend_button: Resend Invitation kudos: guest_header: one: "%{count} guest has also left kudos" diff --git a/db/migrate/20231027172035_add_resent_at_to_invitations.rb b/db/migrate/20231027172035_add_resent_at_to_invitations.rb new file mode 100644 index 00000000000..c95aa1ff884 --- /dev/null +++ b/db/migrate/20231027172035_add_resent_at_to_invitations.rb @@ -0,0 +1,7 @@ +class AddResentAtToInvitations < ActiveRecord::Migration[6.1] + uses_departure! if Rails.env.staging? || Rails.env.production? + + def change + add_column :invitations, :resent_at, :datetime + end +end