azimuth_spree_easy_contact 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. data/LICENSE +23 -0
  2. data/README.md +35 -0
  3. data/app/controllers/admin/contacts_controller.rb +21 -0
  4. data/app/controllers/admin/conversations_controller.rb +24 -0
  5. data/app/controllers/admin/topics_controller.rb +10 -0
  6. data/app/controllers/contacts_controller.rb +32 -0
  7. data/app/helpers/admin/contacts_helper.rb +5 -0
  8. data/app/helpers/admin/conversations_helper.rb +5 -0
  9. data/app/helpers/contacts_helper.rb +5 -0
  10. data/app/mailer/contact_mailer.rb +16 -0
  11. data/app/models/contact.rb +8 -0
  12. data/app/models/conversation.rb +10 -0
  13. data/app/models/topic.rb +7 -0
  14. data/app/views/admin/contacts/index.html.erb +33 -0
  15. data/app/views/admin/contacts/show.html.erb +34 -0
  16. data/app/views/admin/conversations/_contact.html.erb +8 -0
  17. data/app/views/admin/conversations/_new_contact.html.erb +16 -0
  18. data/app/views/admin/conversations/index.html.erb +40 -0
  19. data/app/views/admin/conversations/show.html.erb +26 -0
  20. data/app/views/admin/shared/_contact_tabs.html.erb +15 -0
  21. data/app/views/admin/topics/_form.html.erb +19 -0
  22. data/app/views/admin/topics/edit.html.erb +4 -0
  23. data/app/views/admin/topics/index.html.erb +39 -0
  24. data/app/views/admin/topics/new.html.erb +4 -0
  25. data/app/views/contact_mailer/message_email.text.erb +8 -0
  26. data/app/views/contact_mailer/message_received_email.text.erb +2 -0
  27. data/app/views/contacts/new.html.erb +45 -0
  28. data/config/locales/en.yml +27 -0
  29. data/config/locales/fr-FR.yml +22 -0
  30. data/config/routes.rb +16 -0
  31. data/db/migrate/20110203113622_create_contact_table.rb +16 -0
  32. data/db/migrate/20110207101837_create_topic_table.rb +14 -0
  33. data/db/migrate/20120425223351_add_telephone_to_contact_form.rb +9 -0
  34. data/db/migrate/20120425223352_create_feedback_config_table.rb +15 -0
  35. data/db/migrate/20120425223354_add_conversationid_to_contact.rb +9 -0
  36. data/db/migrate/20120425223355_create_conversation_table.rb +12 -0
  37. data/db/migrate/20130106011856_move_topics_to_conversation.rb +9 -0
  38. data/db/migrate/20130106211248_drop_feedback_configs.rb +9 -0
  39. data/lib/spree_easy_contact.rb +24 -0
  40. data/lib/spree_easy_contact_hooks.rb +43 -0
  41. data/lib/tasks/install.rake +25 -0
  42. data/lib/tasks/spree_easy_contact.rake +1 -0
  43. data/public/images/admin/icons/view.png +0 -0
  44. metadata +114 -0
data/LICENSE ADDED
@@ -0,0 +1,23 @@
1
+ Redistribution and use in source and binary forms, with or without modification,
2
+ are permitted provided that the following conditions are met:
3
+
4
+ * Redistributions of source code must retain the above copyright notice,
5
+ this list of conditions and the following disclaimer.
6
+ * Redistributions in binary form must reproduce the above copyright notice,
7
+ this list of conditions and the following disclaimer in the documentation
8
+ and/or other materials provided with the distribution.
9
+ * Neither the name of the Rails Dog LLC nor the names of its
10
+ contributors may be used to endorse or promote products derived from this
11
+ software without specific prior written permission.
12
+
13
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
14
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
15
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
16
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,35 @@
1
+ SpreeEasyContact
2
+ ================
3
+
4
+ Easy to implement contact form with honeypot-captcha, with a topic selection management in admin.
5
+ It stores all messages in DB for an easy recall of messages.
6
+
7
+ This extension is based on joshnuss spree-contact-form (thank you BTW) : https://github.com/joshnuss/spree-contact-form
8
+
9
+ Installation
10
+ ============
11
+
12
+ Put the following line into your gemfile :
13
+
14
+ gem 'spree_easy_contact'
15
+
16
+ Then run all the following command :
17
+
18
+ bundle install
19
+
20
+ rake spree_easy_contact:install
21
+
22
+ rake db:migrate
23
+
24
+ Set properly the mail method in the admin area (/admin/mail_methods)
25
+
26
+ Add the following to your application initializers:
27
+
28
+ Spree::Config.set(:recaptcha_public_key => '[your_recaptcha_public_key]')
29
+ Spree::Config.set(:recaptcha_private_key => '[your_recaptcha_private_key]')
30
+
31
+ And you're done !
32
+ =================
33
+
34
+
35
+ Copyright (c) 2011 [Mathias Standaert for Organic Web], released under the New BSD License
@@ -0,0 +1,21 @@
1
+ class Admin::ContactsController < Admin::BaseController
2
+ resource_controller
3
+
4
+ def create
5
+ @contact = Conversation.find(params[:contact][:conversation_id]).contacts.build(params[:contact])
6
+ @contact.name = current_user.email.split('@').first
7
+ @contact.email = current_user.email
8
+ respond_to do |format|
9
+ if @contact.valid? && @contact.save
10
+ ContactMailer.message_email(@contact).deliver
11
+ ContactMailer.message_received_email(@contact).deliver
12
+ flash[:notice] = t("message_sent")
13
+ format.html { redirect_to("/admin/conversations/#{@contact.conversation.id}") }
14
+ else
15
+ flash[:notice] = @contact.errors.map{|f,e| "#{f.to_s.humanize} #{e}"}.join(' and ')
16
+ format.html { redirect_to("/admin/conversations/#{@contact.conversation.id}") }
17
+ end
18
+ end
19
+ end
20
+
21
+ end
@@ -0,0 +1,24 @@
1
+ class Admin::ConversationsController < Admin::BaseController
2
+ resource_controller
3
+
4
+ def complete
5
+ @conversation = Conversation.find(params[:id])
6
+ @conversation.status = "closed"
7
+ @conversation.save
8
+ redirect_to :action => :show
9
+ end
10
+
11
+ def index
12
+ @requested_scope = params[:search]
13
+ @requested_scope ||= 'open'
14
+ @conversations = case @requested_scope
15
+ when 'all'
16
+ Conversation.all
17
+ when 'closed'
18
+ Conversation.closed.all
19
+ else
20
+ Conversation.open.all
21
+ end
22
+ end
23
+
24
+ end
@@ -0,0 +1,10 @@
1
+ class Admin::TopicsController < Admin::BaseController
2
+ resource_controller
3
+
4
+ create.wants.html {redirect_to collection_path}
5
+ update.wants.html {redirect_to collection_path}
6
+ new_action.response do |wants|
7
+ wants.html {render :action => :new, :layout => !request.xhr?}
8
+ end
9
+
10
+ end
@@ -0,0 +1,32 @@
1
+ class ContactsController < Spree::BaseController
2
+ before_filter :load_topics
3
+
4
+ def new
5
+ @conversation = Conversation.new
6
+ @contact = Contact.new(:conversation => @conversation)
7
+ end
8
+
9
+ def edit
10
+ redirect_to new_contact_path
11
+ end
12
+
13
+ def create
14
+ @conversation = Conversation.create(:status => "open", :topic_id => params[:conversation][:topic])
15
+ params[:contact][:conversation_id] = @conversation
16
+ @contact = @conversation.contacts.build(params[:contact] || {})
17
+ respond_to do |format|
18
+ if verify_recaptcha(@contact) && @contact.valid? && @contact.save
19
+ ContactMailer.message_email(@contact).deliver
20
+ ContactMailer.message_received_email(@contact).deliver
21
+ format.html { redirect_to(root_path, :notice => t("message_sent")) }
22
+ else
23
+ format.html { render :action => "new" }
24
+ end
25
+ end
26
+ end
27
+
28
+ private
29
+ def load_topics
30
+ @topics = Topic.all
31
+ end
32
+ end
@@ -0,0 +1,5 @@
1
+ module Admin::ContactsHelper
2
+ def link_to_view(resource)
3
+ link_to_with_icon('view', t('view'), object_url(resource))
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Admin::ConversationsHelper
2
+ def link_to_view(resource)
3
+ link_to_with_icon('view', t('view'), object_url(resource))
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module ContactsHelper
2
+ def options_for_current_orders
3
+ options_for_select([''] + current_user.orders.sort_by{|o| o.updated_at }.reverse.map { |o| o.number })
4
+ end
5
+ end
@@ -0,0 +1,16 @@
1
+ class ContactMailer < ActionMailer::Base
2
+ helper "spree/base"
3
+
4
+ # Mails a message to the topic recipients list (internal)
5
+ def message_email(message)
6
+ subject = "#{Spree::Config[:site_name]} - #{t('message_from')} #{message.email}"
7
+
8
+ @message = message
9
+ mail(:to => message.conversation.topic.email, :subject => subject, :reply_to => message.email)
10
+ end
11
+
12
+ # Mails a message to the customer, acknowledging the contact
13
+ def message_received_email(message)
14
+ mail(:to => message.email, :subject => Spree::Config[:auto_response_email_subject], :reply_to => Spree::Config[:auto_response_email_reply_to])
15
+ end
16
+ end
@@ -0,0 +1,8 @@
1
+ class Contact < ActiveRecord::Base
2
+
3
+ validates :name, :presence => true
4
+ validates :email, :format => {:with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i}
5
+ validates :order_number, :format => {:with => /(^$)|(^R\d{9}$)/i, :message => I18n.t("invalid_order_number")}
6
+
7
+ belongs_to :conversation
8
+ end
@@ -0,0 +1,10 @@
1
+ class Conversation < ActiveRecord::Base
2
+ has_many :contacts
3
+ belongs_to :topic
4
+
5
+ validates_presence_of :topic
6
+
7
+ scope :open, where(:status => 'open')
8
+ scope :closed, where(:status => 'closed')
9
+
10
+ end
@@ -0,0 +1,7 @@
1
+ class Topic < ActiveRecord::Base
2
+ has_many :conversations
3
+
4
+ validates :name, :presence => true, :uniqueness => true
5
+ validates :email, :presence => true
6
+
7
+ end
@@ -0,0 +1,33 @@
1
+ <h1><%= t("contacts")%></h1>
2
+ <%= link_to "Topics Admin", admin_topics_path %>
3
+ <table class="index">
4
+ <tr>
5
+ <%= hook :admin_contact_index_headers do %>
6
+ <th><%= t("name") %></th>
7
+ <th><%= t("email") %></th>
8
+ <th><%= t("topic") %></th>
9
+ <th><%= t("sent") %></th>
10
+ <% end %>
11
+ <th>
12
+ <%= hook :admin_contact_index_header_actions %>
13
+ </th>
14
+ </tr>
15
+ <% @contacts.each do |contact| %>
16
+ <tr id="<%= dom_id contact %>">
17
+ <%- locals = {:contact => contact} %>
18
+ <%= hook :admin_contact_index_rows, locals do %>
19
+ <td><%= contact.name %></td>
20
+ <td><%= contact.email %></td>
21
+ <td><%= contact.topic.name %></td>
22
+ <td><%= contact.created_at %></td>
23
+ <% end %>
24
+ <td class="actions">
25
+ <%= hook :admin_contact_index_row_actions, locals do %>
26
+ <%= link_to_view contact %>
27
+ &nbsp;
28
+ <%= link_to_delete contact %>
29
+ <% end %>
30
+ </td>
31
+ </tr>
32
+ <% end %>
33
+ </table>
@@ -0,0 +1,34 @@
1
+ <h1><%= "#{t('contacts')} #{t('from')} #{@contact.name}" %></h1>
2
+
3
+ <%= render :partial => 'admin/shared/contact_tabs', :locals => {:current => "Contact Details"} %>
4
+
5
+ <%= hook :admin_contact_show do %>
6
+ <div class="adr">
7
+ <h4><%= t("name_and_mail") %></h4>
8
+ <p>
9
+ <%= @contact.name %><br />
10
+ <%= @contact.email %><br />
11
+ <%= @contact.telephone %>
12
+ </p>
13
+ </div>
14
+ <div class="adr">
15
+ <h4><%= t("topic") %></h4>
16
+ <p>
17
+ <%= @contact.topic.name %>
18
+ </p>
19
+ </div>
20
+ <% if @contact.order_number %>
21
+ <div class="adr">
22
+ <h4><%= t("order_number") %></h4>
23
+ <p>
24
+ <%= @contact.order_number %>
25
+ </p>
26
+ </div>
27
+ <% end %>
28
+ <div class="adr">
29
+ <h4><%= t("message") %></h4>
30
+ <p>
31
+ <%= @contact.message %>
32
+ </p>
33
+ </div>
34
+ <% end %>
@@ -0,0 +1,8 @@
1
+ <%= hook :admin_contact_show do %>
2
+ <div class="adr" style="clear:both;">
3
+ <h4><%= t("message_from") + " #{contact.name} sent " + contact.created_at.to_s %></h4>
4
+ <p>
5
+ <%= contact.message %>
6
+ </p>
7
+ </div>
8
+ <% end %>
@@ -0,0 +1,16 @@
1
+ <% @body_id = 'contact_us' %>
2
+ <div id="contact-us">
3
+ <h2><%= t("response") %></h2>
4
+ <%= hook :contact do %>
5
+ <%= render "shared/error_messages", :target => contact %>
6
+ <%= form_for(contact, :url => admin_contacts_path(contact)) do |f| %>
7
+ <%= hook :contact_inside_form do %>
8
+ <div class="field">
9
+ <%= f.text_area :message, :cols => '77', :rows => '8' %>
10
+ </div>
11
+ <%= f.hidden_field :conversation_id %>
12
+ <div class="action"><%= f.submit t("send_message"), :class => "button primary" %></div>
13
+ <% end %>
14
+ <% end %>
15
+ <% end %>
16
+ </div>
@@ -0,0 +1,40 @@
1
+ <h1><%= t("#{@requested_scope} conversations")%></h1>
2
+ <%= link_to 'Show Open', admin_conversations_path(:search => 'open') %> |
3
+ <%= link_to 'Show Closed', admin_conversations_path(:search => 'closed') %> |
4
+ <%= link_to 'Show All', admin_conversations_path(:search => 'all') %>
5
+ <br><br>
6
+ <% if @conversations.count == 0 %>
7
+ <h2>There are no <%= @requested_scope %> conversations.</h2>
8
+ <% else %>
9
+ <table class="index">
10
+ <tr>
11
+ <%= hook :admin_conversation_index_headers do %>
12
+ <th><%= t("name") %></th>
13
+ <th><%= t("email") %></th>
14
+ <th><%= t("topic") %></th>
15
+ <th><%= t("sent") %></th>
16
+ <% end %>
17
+ <th>
18
+ <%= hook :admin_conversation_index_header_actions %>
19
+ </th>
20
+ </tr>
21
+ <% @conversations.each do |conversation| %>
22
+ <tr id="<%= dom_id conversation %>">
23
+ <%- locals = {:conversation => conversation} %>
24
+ <%= hook :admin_conversation_index_rows, locals do %>
25
+ <td><%= conversation.contacts.first.name %></td>
26
+ <td><%= conversation.contacts.first.email %></td>
27
+ <td><%= conversation.topic.name %></td>
28
+ <td><%= conversation.created_at %></td>
29
+ <% end %>
30
+ <td class="actions">
31
+ <%= hook :admin_conversation_index_row_actions, locals do %>
32
+ <%= link_to_view conversation %>
33
+ &nbsp;
34
+ <%= link_to_delete conversation %>
35
+ <% end %>
36
+ </td>
37
+ </tr>
38
+ <% end %>
39
+ </table>
40
+ <% end %>
@@ -0,0 +1,26 @@
1
+ <h2>Conversation w/ <%= @conversation.contacts.first.name %>&nbsp;&lt;<%= @conversation.contacts.first.email %>&gt;</h2>
2
+ <p><%= link_to "Show all conversations", admin_conversations_path %></p>
3
+ <h2>RE: <%= @conversation.topic.name %></h2>
4
+ <div class="adr">
5
+ <h4><%= t("details") %></h4>
6
+ <p>
7
+ Name: <%= @conversation.contacts.first.name %><br />
8
+ Email: <%= @conversation.contacts.first.email %><br />
9
+ Phone: <%= @conversation.contacts.first.telephone %><br />
10
+ Order Number: <%= @conversation.contacts.first.order_number ? @conversation.contacts.first.order_number : 'None' %>
11
+ </p>
12
+ <h4><%= t("status") %></h4>
13
+ <% unless @conversation.status == "closed" %>
14
+ <%= form_tag complete_admin_conversation_path do %>
15
+ <%= hidden_field_tag :conversation_id, @conversation.id %>
16
+ <%= submit_tag "Complete" %>
17
+ <% end %>
18
+ <% end %>
19
+ <p><strong><%= @conversation.status.capitalize %></strong> @ <%= @conversation.contacts.first.updated_at.strftime("%b %e, %Y %H:%M %z") %></p>
20
+ </div>
21
+ <div style="clear:both;">
22
+ <%= render :partial => 'contact', :collection => @conversation.contacts %>
23
+ </div>
24
+ <div style="clear:both;">
25
+ <%= render :partial => "new_contact", :locals => { :contact => @conversation.contacts.build } %>
26
+ </div>
@@ -0,0 +1,15 @@
1
+ <% content_for :sidebar do %>
2
+ <ul class="sidebar">
3
+ <%= hook :admin_contact_tabs do %>
4
+ <li<%== ' class="active"' if current == 'Contact List' %>>
5
+ <%= link_to t("contact_list"), collection_url() %>
6
+ </li>
7
+ <li<%== ' class="active"' if current == 'Contact Details' %>>
8
+ <%= link_to t("contact_details"), object_url(@contact) %>
9
+ </li>
10
+ <li<%== ' class="active"' if current == 'Reply' %>>
11
+ <%= link_to t("reply"), "/admin/contacts/new" , {conversation_id: @conversation } %>
12
+ </li>
13
+ <% end %>
14
+ </ul>
15
+ <% end %>
@@ -0,0 +1,19 @@
1
+ <%- locals = {:f => f} %>
2
+
3
+ <%= render "shared/error_messages", :target => f.object %>
4
+
5
+ <%= hook :admin_topic_form, locals do %>
6
+
7
+ <%= f.field_container :name do %>
8
+ <%= f.label :name, t("name") %> <span class="required">*</span><br />
9
+ <%= f.text_field :name, :class => 'fullwidth title' %>
10
+ <%= f.error_message_on :name %>
11
+ <% end %>
12
+
13
+ <%= f.field_container :email do %>
14
+ <%= f.label :email, t("emails") %> (<%= t('comma_delimited') %>) <span class="required">*</span><br />
15
+ <%= f.text_field :email, :class => 'fullwidth title' %>
16
+ <%= f.error_message_on :email %>
17
+ <% end %>
18
+
19
+ <% end %>
@@ -0,0 +1,4 @@
1
+ <%= form_for(@topic, :url => object_url, :html => { :method => :put }) do |f| %>
2
+ <%= render :partial => 'form', :locals => {:f => f} %>
3
+ <%= render :partial => 'admin/shared/edit_resource_links' %>
4
+ <% end %>
@@ -0,0 +1,39 @@
1
+ <div class="toolbar">
2
+ <ul class="actions">
3
+ <li id="new_topic_link">
4
+ <%= button_link_to t("new_topic"), new_object_url, {:remote => true, :icon => "add"} %>
5
+ </li>
6
+ </ul>
7
+ <br class="clear" />
8
+ </div>
9
+ <h1><%= t("topics") %></h1>
10
+
11
+ <div id="new_topic"></div>
12
+
13
+ <table class="index">
14
+ <tr>
15
+ <%= hook :admin_topic_index_header do %>
16
+ <th><%= t("name") %></th>
17
+ <th><%= t("email") %></th>
18
+ <% end %>
19
+ <th>
20
+ <%= hook :admin_topic_index_header_actions %>
21
+ </th>
22
+ </tr>
23
+ <% @topics.each do |topic| %>
24
+ <tr id="dom_id topic">
25
+ <%- locals = {:topic => topic} %>
26
+ <%= hook :admin_topics_index_rows, locals do %>
27
+ <td><%= topic.name %></td>
28
+ <td><%= topic.email %></td>
29
+ <% end %>
30
+ <td class="actions">
31
+ <%= hook :admin_topics_index_rows_actions, locals do %>
32
+ <%= link_to_edit topic %>
33
+ &nbsp;
34
+ <%= link_to_delete topic %>
35
+ <% end %>
36
+ </td>
37
+ </tr>
38
+ <% end %>
39
+ </table>
@@ -0,0 +1,4 @@
1
+ <%= form_for(@topic, :url => collection_url) do |f| %>
2
+ <%= render :partial => 'form', :locals => {:f => f} %>
3
+ <%= render :partial => 'admin/shared/new_resource_links' %>
4
+ <% end %>
@@ -0,0 +1,8 @@
1
+ <%= t('name') %>: <%= @message.name %>
2
+ <%= t('email') %>: <%= @message.email %>
3
+ <%= t('topic') %>: <%= @message.conversation.topic.name %>
4
+ <% unless @message.order_number.blank? %>
5
+ <%= t('order') %>: <%= @message.order_number.upcase %> <%= "http://#{Spree::Config[:site_url]}/admin/orders/#{@message.order_number.upcase}"%>
6
+ <% end %>
7
+
8
+ <%= @message.message %>
@@ -0,0 +1,2 @@
1
+
2
+ <%= Spree::Config[:auto_response_email_body_text] %>
@@ -0,0 +1,45 @@
1
+ <% @body_id = 'contact_us' %>
2
+ <div id="contact-us">
3
+ <h1><%= t("contact_us") %></h1>
4
+ <%= hook :contact do %>
5
+ <%= render "shared/error_messages", :target => @contact %>
6
+ <%= form_for(@contact) do |f| %>
7
+ <%= hook :contact_inside_form do %>
8
+ <div class="field">
9
+ <%= f.label :name, t("name") %><br />
10
+ <%= f.text_field :name, :value => ( current_user && current_user.bill_address ) ? current_user.bill_address.full_name : "" %>
11
+ </div>
12
+ <div class="field">
13
+ <%= f.label :email, t("email") %><br />
14
+ <%= f.text_field :email, :value => current_user ? current_user.email : "" %>
15
+ </div>
16
+ <div class="field">
17
+ <%= f.label :telephone, t("telephone") %><br />
18
+ <%= f.text_field :telephone %>
19
+ </div>
20
+ <div class="field">
21
+ <%= f.label :order_number, t("order_number") %> (<%= t("optional") %>)<br />
22
+ <% if current_user %>
23
+ <%= f.select :order_number, options_for_current_orders %>
24
+ <% else %>
25
+ <%= f.text_field :order_number %>
26
+ <% end %>
27
+ </div>
28
+ <%= fields_for(:conversation) do |ff| %>
29
+ <div class="field">
30
+ <%= ff.label :topic_id, t("topic") %><br />
31
+ <%= ff.collection_select :topic, @topics, :id, :name %>
32
+ </div>
33
+ <% end %>
34
+ <div class="field">
35
+ <%= f.label :message, t("message") %><br />
36
+ <%= f.text_area :message %>
37
+ </div>
38
+ <div class="field">
39
+ <%= raw recaptcha_tags %>
40
+ </div>
41
+ <div class="action"><%= f.submit t("send_message"), :class => "button primary" %></div>
42
+ <% end %>
43
+ <% end %>
44
+ <% end %>
45
+ </div>
@@ -0,0 +1,27 @@
1
+ en:
2
+ contacts: Contacts
3
+ conversations: Conversations
4
+ contact_us: Contact us
5
+ name: Name
6
+ email: Email
7
+ sent: Sent
8
+ view: View
9
+ message: Message
10
+ order_number: Order number
11
+ optional: optional
12
+ name_and_mail: Name and mail
13
+ contact_details: Contact details
14
+ contact_list: Contacts list
15
+ send_message: Send message
16
+ reply: Reply
17
+ message_sent: Your message has been sent. Thank you!
18
+ topics: Contact Form Topic
19
+ topic: Topic
20
+ topics_description: "Setup topics for the contact form, choose wich email should be routed to"
21
+ new_topic: Add a topic
22
+ from: from
23
+ message_from: Message from
24
+ auto_response_email_subject: Response Subject
25
+ auto_response_email_reply_to: Response Reply-To
26
+ auto_response_email_body_html: Response HTML
27
+ auto_response_email_body_text: Response Text
@@ -0,0 +1,22 @@
1
+ fr-FR:
2
+ contacts: Demandes de contact
3
+ conversations: Conversations
4
+ contact_us: Contactez-nous
5
+ name: Nom
6
+ email: Email
7
+ sent: Envoyé le
8
+ view: Voir
9
+ message: Message
10
+ order_number: Numero de commande
11
+ name_and_mail: Nom et email
12
+ contact_details: Détail de la demande
13
+ contact_list: Liste des demandes
14
+ optional: optionnel
15
+ send_message: Envoyer le message
16
+ message_sent: Votre message a été envoyé. Merci!
17
+ topics: Objet des demandes de contact
18
+ topic: Objet
19
+ topics_description: "Créez les objets de demandes de contact, choisissez l'adresse email qui doit lui correspondre"
20
+ new_topic: Ajouter un objet
21
+ from: de
22
+ message_from: Message de
@@ -0,0 +1,16 @@
1
+ Rails.application.routes.draw do
2
+ # add the following (or something similar) to your application's routes.rb file:
3
+ # match '/contact-us' => 'contacts#new', :as => :contact
4
+
5
+ resources :contacts
6
+
7
+ namespace :admin do
8
+ resources :topics
9
+ resources :conversations do
10
+ member do
11
+ post "complete"
12
+ end
13
+ end
14
+ resources :contacts
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ class CreateContactTable < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :contacts do |t|
4
+ t.string :name
5
+ t.string :email
6
+ t.string :order_number
7
+ t.text :message
8
+ t.references :topic
9
+ t.timestamps
10
+ end
11
+ end
12
+
13
+ def self.down
14
+ drop_table :messages
15
+ end
16
+ end
@@ -0,0 +1,14 @@
1
+ class CreateTopicTable < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :topics do |t|
4
+ t.string :name
5
+ t.string :email
6
+
7
+ t.timestamps
8
+ end
9
+ end
10
+
11
+ def self.down
12
+ drop_table :topics
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ class AddTelephoneToContactForm < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :contacts, :telephone, :string
4
+ end
5
+
6
+ def self.down
7
+ drop_column :contacts, :telephone
8
+ end
9
+ end
@@ -0,0 +1,15 @@
1
+ class CreateFeedbackConfigTable < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :feedback_configs do |t|
4
+ t.string :auto_response_email_subject
5
+ t.string :auto_response_email_reply_to
6
+ t.text :auto_response_email_body_html
7
+ t.text :auto_response_email_body_text
8
+ t.timestamps
9
+ end
10
+ end
11
+
12
+ def self.down
13
+ drop_table :feedback_configs
14
+ end
15
+ end
@@ -0,0 +1,9 @@
1
+ class AddConversationidToContact < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :contacts, :conversation_id, :integer
4
+ end
5
+
6
+ def self.down
7
+ drop_column :contacts, :conversation_id
8
+ end
9
+ end
@@ -0,0 +1,12 @@
1
+ class CreateConversationTable < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :conversations do |t|
4
+ t.string :status
5
+ t.timestamps
6
+ end
7
+ end
8
+
9
+ def self.down
10
+ drop_table :conversations
11
+ end
12
+ end
@@ -0,0 +1,9 @@
1
+ class MoveTopicsToConversation < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :conversations, :topic_id, :integer
4
+ remove_column :contacts, :topic_id
5
+ end
6
+
7
+ def self.down
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class DropFeedbackConfigs < ActiveRecord::Migration
2
+ def self.up
3
+ drop_table :feedback_configs
4
+ end
5
+
6
+ def self.down
7
+ raise ActiveRecord::IrreversibleMigration
8
+ end
9
+ end
@@ -0,0 +1,24 @@
1
+ require 'spree_core'
2
+ require 'spree_easy_contact_hooks'
3
+ require 'recaptcha/rails'
4
+
5
+ module SpreeEasyContact
6
+ class Engine < Rails::Engine
7
+
8
+ config.autoload_paths += %W(#{config.root}/lib)
9
+
10
+ def self.activate
11
+ Dir.glob(File.join(File.dirname(__FILE__), "../app/**/*_decorator*.rb")) do |c|
12
+ Rails.env.production? ? require(c) : load(c)
13
+ end
14
+
15
+ Recaptcha.configure do |config|
16
+ config.public_key = Spree::Config[:recaptcha_public_key]
17
+ config.private_key = Spree::Config[:recaptcha_private_key]
18
+ end
19
+ end
20
+
21
+ config.to_prepare &method(:activate).to_proc
22
+
23
+ end
24
+ end
@@ -0,0 +1,43 @@
1
+ class SpreeEasyContactHooks < Spree::ThemeSupport::HookListener
2
+ # custom hooks go here
3
+ insert_after :admin_tabs do
4
+ %(<%= tab(:conversations) %>)
5
+ end
6
+
7
+ insert_after :admin_configurations_menu do
8
+ %(<%= configurations_menu_item(I18n.t('topics'), admin_topics_path, I18n.t('topics_description')) %>)
9
+ end
10
+
11
+ insert_after :admin_general_settings_edit do
12
+ <<-EOT
13
+ <div style="border: black 1px solid; padding: 10px; width: 75%;">
14
+ <h3>Contact Form - Email Settings</h3>
15
+ <p>
16
+ <label for="preferences[auto_response_email_subject]"><%= t("auto_response_email_subject") %></label><br />
17
+ <%= text_field_tag('preferences[auto_response_email_subject]', Spree::Config[:auto_response_email_subject], :size => "100") %>
18
+ </p>
19
+ <p>
20
+ <label for="preferences[auto_response_email_reply_to]"><%= t("auto_response_email_reply_to") %></label><br />
21
+ <%= text_field_tag('preferences[auto_response_email_reply_to]', Spree::Config[:auto_response_email_reply_to], :size => "100") %>
22
+ </p>
23
+ <p>
24
+ <label for="preferences[auto_response_email_body_text]"><%= t("auto_response_email_body_text") %></label><br />
25
+ <%= text_area_tag('preferences[auto_response_email_body_text]', Spree::Config[:auto_response_email_body_text], :cols => "72", :rows => "18") %>
26
+ </p>
27
+ </div>
28
+ EOT
29
+ end
30
+
31
+ insert_before :admin_general_settings_show do
32
+ <<-EOT
33
+ <div style="border: black 1px solid; padding: 10px; width: 75%;">
34
+ <h3>Contact Form - Email Settings</h3>
35
+ <ul>
36
+ <li><span style="font-weight: bold;"><%= t("auto_response_email_subject") %></span>: <%= Spree::Config[:auto_response_email_subject] %></li>
37
+ <li><span style="font-weight: bold;"><%= t("auto_response_email_reply_to") %></span>: <%= Spree::Config[:auto_response_email_reply_to] %></li>
38
+ <li><span style="font-weight: bold;"><%= t("auto_response_email_body_text") %></span>: <%= Spree::Config[:auto_response_email_body_text] %></li>
39
+ </ul>
40
+ </div>
41
+ EOT
42
+ end
43
+ end
@@ -0,0 +1,25 @@
1
+ namespace :spree_easy_contact do
2
+ desc "Copies all migrations and assets (NOTE: This will be obsolete with Rails 3.1)"
3
+ task :install do
4
+ Rake::Task['spree_easy_contact:install:migrations'].invoke
5
+ Rake::Task['spree_easy_contact:install:assets'].invoke
6
+ end
7
+
8
+ namespace :install do
9
+ desc "Copies all migrations (NOTE: This will be obsolete with Rails 3.1)"
10
+ task :migrations do
11
+ source = File.join(File.dirname(__FILE__), '..', '..', 'db')
12
+ destination = File.join(Rails.root, 'db')
13
+ Spree::FileUtilz.mirror_files(source, destination)
14
+ end
15
+
16
+ desc "Copies all assets (NOTE: This will be obsolete with Rails 3.1)"
17
+ task :assets do
18
+ source = File.join(File.dirname(__FILE__), '..', '..', 'public')
19
+ destination = File.join(Rails.root, 'public')
20
+ puts "INFO: Mirroring assets from #{source} to #{destination}"
21
+ Spree::FileUtilz.mirror_files(source, destination)
22
+ end
23
+ end
24
+
25
+ end
@@ -0,0 +1 @@
1
+ # add custom rake tasks here
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: azimuth_spree_easy_contact
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.3
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Mathias Standaert
9
+ - Day Waterbury
10
+ - Rebekah WaterburyChristopher Maujean
11
+ autorequire:
12
+ bindir: bin
13
+ cert_chain: []
14
+ date: 2011-02-08 00:00:00.000000000 Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: spree_core
18
+ requirement: &2152185300 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ! '>='
22
+ - !ruby/object:Gem::Version
23
+ version: 0.40.0
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: *2152185300
27
+ - !ruby/object:Gem::Dependency
28
+ name: recaptcha
29
+ requirement: &2152200300 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ! '>='
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: *2152200300
38
+ description:
39
+ email: contact@organicweb.fr
40
+ executables: []
41
+ extensions: []
42
+ extra_rdoc_files:
43
+ - README.md
44
+ files:
45
+ - README.md
46
+ - LICENSE
47
+ - lib/spree_easy_contact.rb
48
+ - lib/spree_easy_contact_hooks.rb
49
+ - lib/tasks/install.rake
50
+ - lib/tasks/spree_easy_contact.rake
51
+ - app/controllers/admin/contacts_controller.rb
52
+ - app/controllers/admin/conversations_controller.rb
53
+ - app/controllers/admin/topics_controller.rb
54
+ - app/controllers/contacts_controller.rb
55
+ - app/helpers/admin/contacts_helper.rb
56
+ - app/helpers/admin/conversations_helper.rb
57
+ - app/helpers/contacts_helper.rb
58
+ - app/mailer/contact_mailer.rb
59
+ - app/models/contact.rb
60
+ - app/models/conversation.rb
61
+ - app/models/topic.rb
62
+ - app/views/admin/contacts/index.html.erb
63
+ - app/views/admin/contacts/show.html.erb
64
+ - app/views/admin/conversations/_contact.html.erb
65
+ - app/views/admin/conversations/_new_contact.html.erb
66
+ - app/views/admin/conversations/index.html.erb
67
+ - app/views/admin/conversations/show.html.erb
68
+ - app/views/admin/shared/_contact_tabs.html.erb
69
+ - app/views/admin/topics/_form.html.erb
70
+ - app/views/admin/topics/edit.html.erb
71
+ - app/views/admin/topics/index.html.erb
72
+ - app/views/admin/topics/new.html.erb
73
+ - app/views/contact_mailer/message_email.text.erb
74
+ - app/views/contact_mailer/message_received_email.text.erb
75
+ - app/views/contacts/new.html.erb
76
+ - public/images/admin/icons/view.png
77
+ - db/migrate/20110203113622_create_contact_table.rb
78
+ - db/migrate/20110207101837_create_topic_table.rb
79
+ - db/migrate/20120425223351_add_telephone_to_contact_form.rb
80
+ - db/migrate/20120425223352_create_feedback_config_table.rb
81
+ - db/migrate/20120425223354_add_conversationid_to_contact.rb
82
+ - db/migrate/20120425223355_create_conversation_table.rb
83
+ - db/migrate/20130106011856_move_topics_to_conversation.rb
84
+ - db/migrate/20130106211248_drop_feedback_configs.rb
85
+ - config/locales/en.yml
86
+ - config/locales/fr-FR.yml
87
+ - config/routes.rb
88
+ homepage: https://github.com/organicweb/spree-easy-contact
89
+ licenses:
90
+ - BSD
91
+ post_install_message:
92
+ rdoc_options: []
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ! '>='
99
+ - !ruby/object:Gem::Version
100
+ version: 1.8.7
101
+ required_rubygems_version: !ruby/object:Gem::Requirement
102
+ none: false
103
+ requirements:
104
+ - - ! '>='
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements:
108
+ - none
109
+ rubyforge_project:
110
+ rubygems_version: 1.8.16
111
+ signing_key:
112
+ specification_version: 3
113
+ summary: Add gem summary here
114
+ test_files: []