Invite user with custom message and email

James Peret 10 年之前
父節點
當前提交
35ce5902dd

+ 3 - 0
app/assets/javascripts/invites.js.coffee

@@ -0,0 +1,3 @@
1
+# Place all the behaviors and hooks related to the matching controller here.
2
+# All this logic will automatically be available in application.js.
3
+# You can use CoffeeScript in this file: http://coffeescript.org/

+ 4 - 0
app/assets/stylesheets/avalanche_theme.css.less

@@ -25,6 +25,10 @@ html, body {
25 25
 	margin-top: 85px;
26 26
 }
27 27
 
28
+.last-container {
29
+	margin-bottom: 85px;
30
+}
31
+
28 32
 .container-bg {
29 33
 	background-color: @bg-ligh-gray;
30 34
 	margin-top: 0px;

+ 3 - 0
app/assets/stylesheets/invites.css.scss

@@ -0,0 +1,3 @@
1
+// Place all the styles related to the invites controller here.
2
+// They will automatically be included in application.css.
3
+// You can use Sass (SCSS) here: http://sass-lang.com/

+ 31 - 0
app/controllers/invites_controller.rb

@@ -0,0 +1,31 @@
1
+class InvitesController < ApplicationController
2
+  
3
+  def invite
4
+    @invite = Invite.new
5
+  end
6
+  
7
+  def send_invite_message
8
+    @to      = invites_params[:email]
9
+    @message = invites_params[:message]
10
+
11
+    @user = User.invite!({email: @to}, current_user) do |u|
12
+      u.skip_invitation = true
13
+    end
14
+
15
+    UserMailer.invite_message(@user, current_user, @message).deliver if @user.errors.empty?
16
+
17
+    if @user.errors.empty? && @user.update(invitation_sent_at: Time.now.utc)
18
+      flash[:notice] = "successfully sent invite to #{@user.email}"
19
+      redirect_to dashboard_path
20
+    else
21
+      render :invite
22
+    end
23
+  end
24
+  
25
+  private
26
+  
27
+    def invites_params
28
+      params.require(:invite).permit(:email, :message)
29
+    end
30
+  
31
+end

+ 2 - 0
app/helpers/invites_helper.rb

@@ -0,0 +1,2 @@
1
+module InvitesHelper
2
+end

+ 17 - 0
app/mailers/user_mailer.rb

@@ -32,4 +32,21 @@ class UserMailer < ActionMailer::Base
32 32
          :body      => (t 'newsletter_subscription.message')
33 33
   end
34 34
   
35
+  def invite_message(user, from, content)
36
+      @user = user
37
+      @token = user.raw_invitation_token
38
+      invitation_link = accept_user_invitation_url(:invitation_token => @token)
39
+      I18n.with_locale(from.language) do
40
+        mail(:from => from, :bcc => from, :to => @user.email, :subject => (t 'invite_message.email_subject')) do |format|
41
+          content = content.gsub('{{invitation_link}}', invitation_link)
42
+          format.text do
43
+            render :text => content
44
+          end
45
+          format.html do
46
+            render :html => content
47
+          end
48
+        end
49
+      end
50
+  end
51
+  
35 52
 end

+ 3 - 0
app/models/invite.rb

@@ -0,0 +1,3 @@
1
+class Invite < ActiveRecord::Base
2
+  belongs_to :user
3
+end

+ 0 - 18
app/views/agents/invite.html.erb

@@ -1,18 +0,0 @@
1
-<%= content_tag(:div, class: 'container top-container') do %>
2
-	<%= content_tag(:div, class: 'row') do %>
3
-		<%= content_tag(:div, class: 'span12') do %>
4
-			<% # Page Content %>
5
-			<%= bootstrap_flash %>
6
-			<%= content_tag(:div, class: 'page-header') do %>
7
-				<%= content_tag(:h1) do %>
8
-					<%= t 'agent.invite' %>
9
-				<% end %>
10
-			<% end %>
11
-		<% end %>
12
-	<% end %>
13
-	<%= content_tag(:div, class: 'row') do %>
14
-		<%= content_tag(:div, class: 'span12') do %>
15
-		
16
-		<% end %>
17
-	<% end %>
18
-<% end %>

+ 63 - 0
app/views/invites/invite.html.erb

@@ -0,0 +1,63 @@
1
+<%= content_tag(:div, class: 'container top-container last-container') do %>
2
+	<%= content_tag(:div, class: 'row') do %>
3
+		<%= content_tag(:div, class: 'span12') do %>
4
+			<% # Page Content %>
5
+			<%= bootstrap_flash %>
6
+			<%= content_tag(:div, class: 'page-header') do %>
7
+				<%= content_tag(:h1) do %>
8
+					<%= t 'agent.invite' %>
9
+				<% end %>
10
+			<% end %>
11
+		<% end %>
12
+	<% end %>
13
+	<%= content_tag(:div, class: 'row') do %>
14
+		<%= content_tag(:div, class: 'span12') do %>
15
+		
16
+			<%= bootstrap_form_for(@invite, :url => { controller: 'invites', action: 'send_invite_message' } ) do |f| %>
17
+	
18
+				<% # Mission Agent Details Group %>
19
+				<%= content_tag(:div, class: 'row') do %>
20
+					<% # Form - Mission Agent Details %>
21
+					<%= content_tag(:div, class: 'span8') do %>
22
+						<%= f.alert_message "Please fix the errors below." %>
23
+							<%= content_tag(:div, class: 'panel panel-default') do %>
24
+							<%= content_tag(:div, class: 'panel-body white-bg') do %>
25
+								<%= content_tag(:div, class: "panel-content") do %>
26
+									<%= content_tag(:div, class: "panel-text") do %>
27
+										<%= content_tag(:div, class: "form-inputs") do %>
28
+										    <%= f.text_field :email, label: (t 'invite.email'), class: 'input-block-level' %>
29
+										    <%= f.text_area :message, label: (t 'invite.message'), class: 'input-block-level', rows: 10 %>
30
+										<% end %>
31
+									<% end %>
32
+								<% end %>
33
+							<% end %>
34
+							<% # Form - Submit %>
35
+							<%= content_tag(:div, class: "form-submit-center") do %>
36
+								<%= content_tag(:p) do %>
37
+									<%= f.submit (t 'invite.send'), class: 'btn btn-large btn-success spacer-left-small' %>
38
+								<% end %>
39
+							<% end %>
40
+						<% end %>
41
+					<% end %>
42
+					<% # Sidebar - Mission Agent Details %>
43
+					<%= content_tag(:div, class: 'span4 sidebar') do %>
44
+					     <%= content_tag(:div, class: 'panel panel-default sidebar-carret') do %>
45
+					     	<%= content_tag(:div, class: 'panel-body white-bg') do %>
46
+						   		<%= content_tag(:div, class: "panel-content") do %>
47
+						   			<%= content_tag(:div, class: "panel-text") do %>
48
+										<%= content_tag(:h3, (t 'mission_editor.agents.agent_details_help_title')) %>
49
+										<%= content_tag(:div, (t 'mission_editor.agents.agent_details_help').html_safe, class: 'small-text') %>
50
+									<% end %>
51
+								<% end %>
52
+							<% end %>
53
+						<% end %>
54
+					<% end %>
55
+				<% end %>
56
+
57
+
58
+			<% end %>
59
+		
60
+		
61
+		<% end %>
62
+	<% end %>
63
+<% end %>

+ 37 - 5
app/views/missions/_mission_editor_tabs.html.erb

@@ -5,29 +5,61 @@
5 5
 				<%= content_tag(:div, '', class: 'line')%>
6 6
 				
7 7
 				<%= content_tag(:ul, class: 'steps') do %>
8
-					<%= content_tag(:li, class: 'step') do %>
9
-						<%= link_to(mission_editor_path(@mission)) do %>
8
+					<% # Mission Details %>
9
+					<% if params[:action] == 'new' %>
10
+						<%= content_tag(:li, class: 'step') do %>
10 11
 							<%= content_tag(:div, '1', class: "circle #{'current' if params[:action] == 'edit' && params[:controller] == 'missions'}") %><br>
11 12
 							<%= content_tag(:div, (t 'mission_editor.mission_details.mission_details'), class: 'description current') %>
12 13
 						<% end %>
14
+					<% else %>
15
+						<%= content_tag(:li, class: 'step') do %>
16
+							<%= link_to(mission_editor_path(@mission)) do %>
17
+								<%= content_tag(:div, '1', class: "circle #{'current' if params[:action] == 'edit' && params[:controller] == 'missions'}") %><br>
18
+								<%= content_tag(:div, (t 'mission_editor.mission_details.mission_details'), class: 'description current') %>
19
+							<% end %>
20
+						<% end %>
13 21
 					<% end %>
14
-					<%= link_to(rewards_path(@mission)) do %>
22
+					<% # Rewards %>
23
+					<% if params[:action] == 'new' %>
15 24
 						<%= content_tag(:li, class: 'step') do %>
16 25
 							<%= content_tag(:div, '2', class: "circle #{'current' if params[:controller] == 'mission_editor/rewards'}") %><br>
17 26
 							<%= content_tag(:div, (t 'mission_editor.mission_details.rewards'), class: 'description') %>
18 27
 						<% end %>
28
+					<% else %>
29
+						<%= link_to(rewards_path(@mission)) do %>
30
+							<%= content_tag(:li, class: 'step') do %>
31
+								<%= content_tag(:div, '2', class: "circle #{'current' if params[:controller] == 'mission_editor/rewards'}") %><br>
32
+								<%= content_tag(:div, (t 'mission_editor.mission_details.rewards'), class: 'description') %>
33
+							<% end %>
34
+						<% end %>
19 35
 					<% end %>
20
-					<%= link_to(mission_agents_path(@mission)) do %>
36
+					<% # Agents %>
37
+					<% if params[:action] == 'new' %>
21 38
 						<%= content_tag(:li, class: 'step') do %>
22 39
 							<%= content_tag(:div, '3', class: "circle #{'current' if params[:controller] == 'mission_editor/agents'}") %><br>
23 40
 							<%= content_tag(:div, (t 'mission_editor.mission_details.agents'), class: 'description') %>
24 41
 						<% end %>
42
+					<% else %>
43
+						<%= link_to(mission_agents_path(@mission)) do %>
44
+							<%= content_tag(:li, class: 'step') do %>
45
+								<%= content_tag(:div, '3', class: "circle #{'current' if params[:controller] == 'mission_editor/agents'}") %><br>
46
+								<%= content_tag(:div, (t 'mission_editor.mission_details.agents'), class: 'description') %>
47
+							<% end %>
48
+						<% end %>
25 49
 					<% end %>
26
-					<%= link_to(mission_editor_launch_path(@mission)) do %>
50
+					<% # Launch %>
51
+					<% if params[:action] == 'new' %>
27 52
 						<%= content_tag(:li, class: 'step') do %>
28 53
 							<%= content_tag(:div, '4', class: "circle #{'current' if params[:controller] == 'mission_editor/details'}") %><br>
29 54
 							<%= content_tag(:div, (t 'mission_editor.mission_details.launch'), class: 'description') %>
30 55
 						<% end %>
56
+					<% else %>
57
+						<%= link_to(mission_editor_launch_path(@mission)) do %>
58
+							<%= content_tag(:li, class: 'step') do %>
59
+								<%= content_tag(:div, '4', class: "circle #{'current' if params[:controller] == 'mission_editor/details'}") %><br>
60
+								<%= content_tag(:div, (t 'mission_editor.mission_details.launch'), class: 'description') %>
61
+							<% end %>
62
+						<% end %>
31 63
 					<% end %>
32 64
 				<% end %>
33 65
 			<% end %>

+ 3 - 5
app/views/devise/mailer/invitation_instructions.html.erb

@@ -1,9 +1,7 @@
1
-<p><%= I18n.t("devise.mailer.invitation_instructions.hello", email: @resource.email) %></p>
1
+<p><%= I18n.t("devise.mailer.invitation_instructions.hello", email: @user.email) %></p>
2 2
 
3 3
 <p><%= I18n.t("devise.mailer.invitation_instructions.someone_invited_you", url: root_url) %></p>
4 4
 
5
-<p><%= link_to I18n.t("devise.mailer.invitation_instructions.accept"), accept_invitation_url(@resource, :invitation_token => @token) %></p>
5
+<p><%= link_to I18n.t("devise.mailer.invitation_instructions.accept"), accept_invitation_url(@user, :invitation_token => @token) %></p>
6 6
 
7
-<p><%= I18n.t("devise.mailer.invitation_instructions.ignore").html_safe %></p>
8
-
9
-<p><%= mission.title %></p>
7
+<p><%= I18n.t("devise.mailer.invitation_instructions.ignore").html_safe %></p>

+ 2 - 1
config/locales/email.en.yml

@@ -19,4 +19,5 @@ en:
19 19
     step4: 'Complete the mission'
20 20
     step5: 'Win rewards'
21 21
     start: 'Start'
22
-    
22
+  invite:
23
+    send: 'Send Invite'

+ 4 - 1
config/routes.rb

@@ -58,7 +58,10 @@ Avalanche2::Application.routes.draw do
58 58
   get 'dashboard/directing' => 'agents#directing_missions', as: :directing_missions
59 59
   get 'agents' => 'agents#list', as: :agent_list
60 60
   get 'agent/:id' => 'agents#show', as: :show_agent
61
-  get 'invite' => 'agents#invite', as: :invite
61
+  
62
+  # Invites
63
+  get 'invite' => 'invites#invite', as: :invite
64
+  post 'send_invite_message' => 'invites#send_invite_message', as: :send_invite_message
62 65
   
63 66
   # Rewards
64 67
   get 'dashboard/rewards' => 'agents#rewards', as: :user_rewards

+ 14 - 0
db/migrate/20150417040350_create_invites.rb

@@ -0,0 +1,14 @@
1
+class CreateInvites < ActiveRecord::Migration
2
+  def change
3
+    create_table :invites do |t|
4
+      t.string :email
5
+      t.text :message
6
+      t.references :user, index: true
7
+      t.boolean :invited
8
+      t.string :invitations_sent
9
+      t.datetime :last_invitation_sent_date
10
+
11
+      t.timestamps
12
+    end
13
+  end
14
+end

+ 14 - 1
db/schema.rb

@@ -11,7 +11,7 @@
11 11
 #
12 12
 # It's strongly recommended that you check this file into your version control system.
13 13
 
14
-ActiveRecord::Schema.define(version: 20150416214326) do
14
+ActiveRecord::Schema.define(version: 20150417040350) do
15 15
 
16 16
   # These are extensions that must be enabled in order to support this database
17 17
   enable_extension "plpgsql"
@@ -91,6 +91,19 @@ ActiveRecord::Schema.define(version: 20150416214326) do
91 91
     t.string   "server_email"
92 92
   end
93 93
 
94
+  create_table "invites", force: true do |t|
95
+    t.string   "email"
96
+    t.text     "message"
97
+    t.integer  "user_id"
98
+    t.boolean  "invited"
99
+    t.string   "invitations_sent"
100
+    t.datetime "last_invitation_sent_date"
101
+    t.datetime "created_at"
102
+    t.datetime "updated_at"
103
+  end
104
+
105
+  add_index "invites", ["user_id"], name: "index_invites_on_user_id", using: :btree
106
+
94 107
   create_table "mission_agents", force: true do |t|
95 108
     t.integer  "mission_id"
96 109
     t.integer  "agent_steps_id"

二進制
dump.rdb


+ 7 - 0
test/controllers/invites_controller_test.rb

@@ -0,0 +1,7 @@
1
+require 'test_helper'
2
+
3
+class InvitesControllerTest < ActionController::TestCase
4
+  # test "the truth" do
5
+  #   assert true
6
+  # end
7
+end

+ 17 - 0
test/fixtures/invites.yml

@@ -0,0 +1,17 @@
1
+# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
2
+
3
+one:
4
+  email: MyString
5
+  message: MyText
6
+  user_id: 
7
+  invited: false
8
+  invitations_sent: MyString
9
+  last_invitation_sent_date: 2015-04-17 01:03:50
10
+
11
+two:
12
+  email: MyString
13
+  message: MyText
14
+  user_id: 
15
+  invited: false
16
+  invitations_sent: MyString
17
+  last_invitation_sent_date: 2015-04-17 01:03:50

+ 4 - 0
test/helpers/invites_helper_test.rb

@@ -0,0 +1,4 @@
1
+require 'test_helper'
2
+
3
+class InvitesHelperTest < ActionView::TestCase
4
+end

+ 7 - 0
test/models/invite_test.rb

@@ -0,0 +1,7 @@
1
+require 'test_helper'
2
+
3
+class InviteTest < ActiveSupport::TestCase
4
+  # test "the truth" do
5
+  #   assert true
6
+  # end
7
+end