diff --git a/app/controllers/admin/contacts_controller.rb b/app/controllers/admin/contacts_controller.rb new file mode 100644 index 00000000..4455a3cb --- /dev/null +++ b/app/controllers/admin/contacts_controller.rb @@ -0,0 +1,44 @@ +class Admin::ContactsController < ApplicationController + before_action :set_conference + before_action :set_contact, only: [:show, :edit, :update, :destroy] + + # GET /:conference/contact + def show + end + + # GET /:conference/contact/edit + def edit + end + + # PATCH/PUT /:conference/contact + def update + if @contact.update(contact_params) + redirect_to admin_conference_contact_path, notice: 'Contact details were successfully updated.' + else + render :edit + end + end + + # DELETE /:conference/contact + def destroy + @contact.destroy + redirect_to admin_conference_contacts_url, notice: 'Contact details were successfully destroyed.' + end + + private + + # Use callbacks to share common setup or constraints between actions. + def set_contact + @contact = @conference.contact + end + + def set_conference + @conference = Conference.find_by(short_title: params[:conference_id]) + end + + # Only allow a trusted parameter "white list" through. + def contact_params + # params.require(:contact).permit(:social_tag, :email, :facebook, :googleplus, :twitter, :instagram, :public) + params[:contact] + end +end diff --git a/app/controllers/conference_registration_controller.rb b/app/controllers/conference_registration_controller.rb index 025e09d3..6a8acd87 100644 --- a/app/controllers/conference_registration_controller.rb +++ b/app/controllers/conference_registration_controller.rb @@ -37,7 +37,7 @@ class ConferenceRegistrationController < ApplicationController if regs.where(email: user.email).count == 0 redirect_to(register_conference_path(id: conference.short_title), alert: "This code is already in use. - Please contact #{conference.contact_email} for assistance.") + Please contact #{conference.contact.email} for assistance.") return end end diff --git a/app/mailers/mailbot.rb b/app/mailers/mailbot.rb index fd7c9d62..74bb4224 100644 --- a/app/mailers/mailbot.rb +++ b/app/mailers/mailbot.rb @@ -83,8 +83,8 @@ class Mailbot < ActionMailer::Base def build_email(conference, to, subject, body) mail(to: to, - from: conference.contact_email, - reply_to: conference.contact_email, + from: conference.contact.email, + reply_to: conference.contact.email, subject: subject, body: body) end diff --git a/app/models/conference.rb b/app/models/conference.rb index 68b9aad0..1477fe3a 100644 --- a/app/models/conference.rb +++ b/app/models/conference.rb @@ -5,7 +5,7 @@ class Conference < ActiveRecord::Base require 'uri' serialize :events_per_week, Hash - attr_accessible :title, :short_title, :social_tag, :contact_email, :timezone, :html_export_path, + attr_accessible :title, :short_title, :timezone, :html_export_path, :start_date, :end_date, :rooms_attributes, :tracks_attributes, :dietary_choices_attributes, :use_dietary_choices, :use_supporter_levels, :supporter_levels_attributes, :social_events_attributes, :event_types_attributes, @@ -14,19 +14,21 @@ class Conference < ActiveRecord::Base :use_difficulty_levels, :use_vpositions, :use_vdays, :vdays_attributes, :vpositions_attributes, :use_volunteers, :media_id, :media_type, :color, :description, :registration_description, :ticket_description, - :sponsorship_levels_attributes, :sponsors_attributes, :facebook_url, :google_url, - :twitter_url, :sponsor_description, :sponsor_email, :lodging_description, + :sponsorship_levels_attributes, :sponsors_attributes, + :sponsor_description, :sponsor_email, :lodging_description, :include_registrations_in_splash, :include_sponsors_in_splash, :include_tracks_in_splash, :include_tickets_in_splash, - :include_social_media_in_splash, :include_program_in_splash, + :include_program_in_splash, :make_conference_public, :photos_attributes, :banner_photo, :include_banner_in_splash, :targets, :targets_attributes, :campaigns, - :campaigns_attributes, :instagram_url + :campaigns_attributes has_paper_trail has_and_belongs_to_many :questions + has_one :contact, dependent: :destroy + has_one :email_settings, dependent: :destroy has_one :call_for_papers, dependent: :destroy has_many :social_events, dependent: :destroy @@ -81,13 +83,9 @@ class Conference < ActiveRecord::Base size: { in: 0..500.kilobytes } validates_presence_of :title, :short_title, - :social_tag, :start_date, :end_date - validates :facebook_url, :twitter_url, :google_url, - format: URI::regexp(%w(http https)), allow_blank: true - validates_uniqueness_of :short_title validates_format_of :short_title, with: /\A[a-zA-Z0-9_-]*\z/ before_create :generate_guid @@ -523,6 +521,10 @@ class Conference < ActiveRecord::Base private + after_create do + self.create_contact + end + ## # Calculates the weeks from a start and a end week. # diff --git a/app/models/contact.rb b/app/models/contact.rb new file mode 100644 index 00000000..a4e28035 --- /dev/null +++ b/app/models/contact.rb @@ -0,0 +1,11 @@ +class Contact < ActiveRecord::Base + attr_accessible :conference_id, :social_tag, :email, :facebook, :googleplus, :twitter, :instagram, :public + belongs_to :conference + + validates :conference, presence: true + # Conferences only have one contact + validates :conference_id, uniqueness: {message: "has already contact details"} + + validates :facebook, :twitter, :googleplus, :instagram, + format: URI::regexp(%w(http https)), allow_blank: true +end diff --git a/app/serializers/conference_serializer.rb b/app/serializers/conference_serializer.rb index f8b4ddb2..1566e9da 100644 --- a/app/serializers/conference_serializer.rb +++ b/app/serializers/conference_serializer.rb @@ -10,7 +10,7 @@ class ConferenceSerializer < ActiveModel::Serializer end def socialtag - object.social_tag + object.contact.social_tag end def revision diff --git a/app/views/admin/conference/edit.html.haml b/app/views/admin/conference/edit.html.haml index cf5eeee8..5cecd8a8 100644 --- a/app/views/admin/conference/edit.html.haml +++ b/app/views/admin/conference/edit.html.haml @@ -6,8 +6,6 @@ = f.input :include_program_in_splash, hint: 'On setting this true you will enable the program component to be displayed on the splash page.This component includes tracks, keynote speakers and the schedule' = f.input :title, :hint => "The full name of the conference, such as 'OpenSUSE Conference 2013'" = f.input :short_title, :hint => "A short title, such as 'osc2013', to be used in URLs" - = f.input :social_tag, :hint => "The hashtag you'll use on Twitter and Google+. Don't include the '#' sign!'" - = f.input :contact_email, :hint => "Contact email address for your conference. Will be used as reply-to address in emails sent out by the system." = f.input :color, :hint => "The color will be used eg for the dashboard.", :input_html => {:size => 6, :type => "color"} = f.inputs name: 'Banner for Splash' do = f.input :include_banner_in_splash, hint: 'This enable the Banner Photo with description to be displayed on the splash' @@ -33,7 +31,6 @@ = f.inputs :name => 'Social Media' do - if !@conference.logo.blank? = image_tag @conference.logo(:thumb) - = f.input :include_social_media_in_splash, hint: 'On setting this true you will enable the social media links to be displayed on the splash page' = f.input :logo, :label => "Conference Logo", :hint => "This will be displayed on the front page." = f.input :media_type, :as => :select, :label => "Conference Promo Media Type", :class=>"form-control", :collection => Conference.media_types.values, :include_blank => false, :hint => "This media-item will be used to represent this conference at various places in OSEM." = f.input :media_id, :label => "Conference Promo Media ID", :as => :string @@ -43,8 +40,4 @@ %p{:class => "help-block media-type", :id => "vimeo-help", :style => "display:none"} Go to your vimeo video, click on "share" and copy everything behind http://vimeo.com/ %p{:class => "help-block media-type", :id => "speakerdeck-help", :style => "display:none"} Go to your SpeakerDeck, click on "share" -> "embed" and copy the data-id %p{:class => "help-block media-type", :id => "instagram-help", :style => "display:none"} Go to your Instagram photo page and copy everything behind instagram.com/p/ (without trailing /# hash symbol) - = f.input :facebook_url, hint: 'This will appear in the social media section as link to the Facebook page of your Conference' - = f.input :google_url, label: 'Google+ Url', hint: 'This will appear in the social media section as the link to the Google+ Page of your Conference' - = f.input :twitter_url, hint: 'This will appear in the social media section as the link to the Twitter Page of your Conference' - = f.input :instagram_url, hint: 'This will appear in the social media section as the link to the Instagram Page of your Conference' = f.action :submit, :as => :button, :button_html => {:class => "btn btn-primary"} diff --git a/app/views/admin/conference/new.html.haml b/app/views/admin/conference/new.html.haml index 7aa155f2..88d10d36 100644 --- a/app/views/admin/conference/new.html.haml +++ b/app/views/admin/conference/new.html.haml @@ -6,9 +6,6 @@ input_html: { required: 'required' } = f.input :short_title, hint: "A short and unique handle for your conference, using only lower-case letters, numbers and underscores. This will be used to identify your conference in URLs etc. Example: 'froscon2011'", input_html: { required: 'required' } - = f.input :social_tag, hint: "The hashtag you'll use on Twitter and Google+. Don't include the '#' sign!'", - input_html: { required: 'required' } - = f.input :contact_email, hint: 'Contact email address for your conference. Will be used as reply-to address in emails sent out by the system.' = f.inputs 'Scheduling' do = f.input :timezone, as: :time_zone, hint: 'Please select in what time zone your conference will take place.' = f.input :start_date, as: :string, input_html: { id: 'conference-start-datepicker', required: 'required' } diff --git a/app/views/admin/contacts/_form.html.haml b/app/views/admin/contacts/_form.html.haml new file mode 100644 index 00000000..8113ebd3 --- /dev/null +++ b/app/views/admin/contacts/_form.html.haml @@ -0,0 +1,31 @@ += form_for @contact, url: admin_conference_contact_path do |f| + - if @contact.errors.any? + #error_explanation + %h2= "#{pluralize(@contact.errors.count, "error")} prohibited this contact from being saved:" + %ul + - @contact.errors.full_messages.each do |msg| + %li= msg + + .field + = f.label :social_tag + = f.text_field :social_tag + .field + = f.label :email + = f.text_field :email + .field + = f.label :facebook + = f.text_field :facebook + .field + = f.label :googleplus + = f.text_field :googleplus + .field + = f.label :twitter + = f.text_field :twitter + .field + = f.label :instagram + = f.text_field :instagram + .field + = f.label :public + = f.check_box :public + .actions + = f.submit 'Save' diff --git a/app/views/admin/contacts/edit.html.haml b/app/views/admin/contacts/edit.html.haml new file mode 100644 index 00000000..f3dc61f9 --- /dev/null +++ b/app/views/admin/contacts/edit.html.haml @@ -0,0 +1,5 @@ +%h1 Editing contact + += render 'form' + += link_to 'Back', admin_conference_contact_path diff --git a/app/views/admin/contacts/show.html.haml b/app/views/admin/contacts/show.html.haml new file mode 100644 index 00000000..d73f904f --- /dev/null +++ b/app/views/admin/contacts/show.html.haml @@ -0,0 +1,26 @@ +%p#notice= notice + +%p + %b Social tag: + = @contact.social_tag +%p + %b Email: + = @contact.email +%p + %b Facebook: + = @contact.facebook +%p + %b Googleplus: + = @contact.googleplus +%p + %b Twitter: + = @contact.twitter +%p + %b Instagram: + = @contact.instagram +%p + %b Public: + = @contact.public + += link_to 'Edit', edit_admin_conference_contact_path + diff --git a/app/views/conference/_social_media.html.haml b/app/views/conference/_social_media.html.haml index 2edcd09c..7aca46bd 100644 --- a/app/views/conference/_social_media.html.haml +++ b/app/views/conference/_social_media.html.haml @@ -4,19 +4,19 @@ %div.container#social-media.text-center %div.row - - unless @conference.facebook_url.blank? + - unless @conference.contact.facebook.blank? %div.col-md-3 - = link_to "#{ @conference.facebook_url }" do + = link_to "#{ @conference.contact.facebook }" do %i.fa.fa-facebook-square.fa-4x - - unless @conference.twitter_url.blank? + - unless @conference.contact.twitter.blank? %div.col-md-3 - = link_to "#{ @conference.twitter_url }" do + = link_to "#{ @conference.contact.twitter }" do %i.fa.fa-twitter.fa-4x - - unless @conference.instagram_url.blank? + - unless @conference.contact.instagram.blank? %div.col-md-3 - = link_to "#{ @conference.instagram_url }" do + = link_to "#{ @conference.contact.instagram }" do %i.fa.fa-instagram.fa-4x - - unless @conference.google_url.blank? + - unless @conference.contact.googleplus.blank? %div.col-md-3 - = link_to "#{ @conference.google_url }" do + = link_to "#{ @conference.contact.googleplus }" do %i.fa.fa-google-plus-square.fa-4x diff --git a/app/views/conference/show.html.haml b/app/views/conference/show.html.haml index 0ece7865..b1014821 100644 --- a/app/views/conference/show.html.haml +++ b/app/views/conference/show.html.haml @@ -52,7 +52,7 @@ .pad = render 'sponsor' - - if @conference.include_social_media_in_splash? + - if @conference.contact.public? %section{ id: 'social-media' } .pad = render 'social_media' diff --git a/config/routes.rb b/config/routes.rb index 20c43a75..3f43dd17 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -8,6 +8,7 @@ Osem::Application.routes.draw do resources :users resources :people resources :conference do + resource :contact, except: [:index, :new, :create] resource :schedule, only: [:show, :update] get '/stats' => 'stats#index' get '/venue' => 'venue#show', as: 'venue_info' diff --git a/db/migrate/20140731153332_create_contacts.rb b/db/migrate/20140731153332_create_contacts.rb new file mode 100644 index 00000000..df1b3ce7 --- /dev/null +++ b/db/migrate/20140731153332_create_contacts.rb @@ -0,0 +1,17 @@ +class CreateContacts < ActiveRecord::Migration + def change + create_table :contacts do |t| + t.string :social_tag + t.string :email + t.string :facebook + t.string :googleplus + t.string :twitter + t.string :instagram + + t.boolean :public + t.integer :conference_id + + t.timestamps + end + end +end diff --git a/db/migrate/20140731165107_move_conference_contact_details_to_contact.rb b/db/migrate/20140731165107_move_conference_contact_details_to_contact.rb new file mode 100644 index 00000000..1bbbbb4f --- /dev/null +++ b/db/migrate/20140731165107_move_conference_contact_details_to_contact.rb @@ -0,0 +1,34 @@ +class MoveConferenceContactDetailsToContact < ActiveRecord::Migration + class TempConference < ActiveRecord::Base + self.table_name = 'conferences' + end + + class TempContact < ActiveRecord::Base + self.table_name = 'contacts' + attr_accessible :conference_id, :social_tag, :email, :facebook, :googleplus, :twitter, :instagram, :public + end + + def change + # Move all the settings to the new object + TempConference.all.each do |conference| + unless TempContact.exists?(conference_id: conference.id) + TempContact.create(social_tag: conference.social_tag, + email: conference.contact_email, + facebook: conference.facebook_url, + googleplus: conference.google_url, + twitter: conference.twitter_url, + instagram: conference.instagram_url, + public: conference.include_social_media_in_splash, + conference_id: conference.id) + end + end + # Then remove all the columns + remove_column :conferences, :social_tag + remove_column :conferences, :contact_email + remove_column :conferences, :facebook_url + remove_column :conferences, :google_url + remove_column :conferences, :twitter_url + remove_column :conferences, :instagram_url + remove_column :conferences, :include_social_media_in_splash + end +end diff --git a/db/schema.rb b/db/schema.rb index 4f112525..88eff61d 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20140724113107) do +ActiveRecord::Schema.define(version: 20140731165107) do create_table "ahoy_events", force: true do |t| t.uuid "visit_id" @@ -78,8 +78,6 @@ ActiveRecord::Schema.define(version: 20140724113107) do t.string "guid", null: false t.string "title", null: false t.string "short_title", null: false - t.string "social_tag" - t.string "contact_email", null: false t.string "timezone", null: false t.string "html_export_path" t.date "start_date", null: false @@ -108,23 +106,18 @@ ActiveRecord::Schema.define(version: 20140724113107) do t.text "ticket_description" t.text "sponsor_description" t.string "sponsor_email" - t.string "twitter_url" - t.string "facebook_url" - t.string "google_url" t.text "lodging_description" t.boolean "make_conference_public", default: false t.boolean "include_registrations_in_splash", default: false t.boolean "include_sponsors_in_splash", default: false t.boolean "include_tracks_in_splash", default: false t.boolean "include_tickets_in_splash", default: false - t.boolean "include_social_media_in_splash", default: false t.boolean "include_program_in_splash", default: false t.string "banner_photo_file_name" t.string "banner_photo_content_type" t.integer "banner_photo_file_size" t.datetime "banner_photo_updated_at" t.boolean "include_banner_in_splash", default: false - t.string "instagram_url" t.text "events_per_week" end @@ -133,6 +126,19 @@ ActiveRecord::Schema.define(version: 20140724113107) do t.integer "question_id" end + create_table "contacts", force: true do |t| + t.string "social_tag" + t.string "email" + t.string "facebook" + t.string "googleplus" + t.string "twitter" + t.string "instagram" + t.boolean "public" + t.integer "conference_id" + t.datetime "created_at" + t.datetime "updated_at" + end + create_table "delayed_jobs", force: true do |t| t.integer "priority", default: 0, null: false t.integer "attempts", default: 0, null: false @@ -487,8 +493,8 @@ ActiveRecord::Schema.define(version: 20140724113107) do create_table "venues", force: true do |t| t.string "guid" - t.text "name", limit: 255 - t.text "address", limit: 255 + t.text "name" + t.text "address" t.string "website" t.text "description" t.string "offline_map_url" @@ -499,8 +505,8 @@ ActiveRecord::Schema.define(version: 20140724113107) do t.string "photo_content_type" t.integer "photo_file_size" t.datetime "photo_updated_at" - t.boolean "include_venue_in_splash", default: false - t.boolean "include_lodgings_in_splash", default: false + t.boolean "include_venue_in_splash", default: false + t.boolean "include_lodgings_in_splash", default: false end create_table "versions", force: true do |t| diff --git a/spec/factories/conferences.rb b/spec/factories/conferences.rb index 4b7be4be..2ebde9f5 100644 --- a/spec/factories/conferences.rb +++ b/spec/factories/conferences.rb @@ -4,9 +4,7 @@ FactoryGirl.define do factory :conference do title 'The dog and pony show' sequence(:short_title) { |n| "dps#{n}14" } - social_tag 'dps14' timezone 'Amsterdam' - contact_email 'admin@example.com' start_date { Date.today } end_date { 6.days.from_now } registration_start_date { 3.days.from_now } diff --git a/spec/features/conference_spec.rb b/spec/features/conference_spec.rb index 06fb21dc..4476044d 100644 --- a/spec/features/conference_spec.rb +++ b/spec/features/conference_spec.rb @@ -15,7 +15,6 @@ feature Conference do visit new_admin_conference_path fill_in 'conference_title', with: 'Example Con' fill_in 'conference_short_title', with: 'ExCon' - fill_in 'conference_social_tag', with: 'ExCon' select('(GMT+01:00) Berlin', from: 'conference[timezone]') @@ -42,7 +41,6 @@ feature Conference do visit edit_admin_conference_path(conference.short_title) fill_in 'conference_title', with: 'New Con' fill_in 'conference_short_title', with: 'NewCon' - fill_in 'conference_social_tag', with: 'NewCon' click_button 'Update Conference' expect(flash). @@ -51,7 +49,6 @@ feature Conference do conference.reload expect(conference.title).to eq('New Con') expect(conference.short_title).to eq('NewCon') - expect(conference.social_tag).to eq('NewCon') expect(Conference.count).to eq(expected_count) end end diff --git a/spec/models/conference_spec.rb b/spec/models/conference_spec.rb index 885ba09c..e3897702 100644 --- a/spec/models/conference_spec.rb +++ b/spec/models/conference_spec.rb @@ -1457,10 +1457,6 @@ describe Conference do should validate_presence_of(:short_title) end - it 'is not valid without a social tag' do - should validate_presence_of(:social_tag) - end - it 'is not valid without a start date' do should validate_presence_of(:start_date) end diff --git a/spec/views/admin/conference/edit.html.haml_spec.rb b/spec/views/admin/conference/edit.html.haml_spec.rb index d9b20a42..713956d2 100644 --- a/spec/views/admin/conference/edit.html.haml_spec.rb +++ b/spec/views/admin/conference/edit.html.haml_spec.rb @@ -7,6 +7,5 @@ describe 'admin/conference/edit' do assign :conference, @conference render template: 'admin/conference/edit.html.haml' expect(rendered).to include('OpenSUSE') - expect(rendered).to include("#{@conference.contact_email}") end end diff --git a/spec/views/conference/show.html.haml_spec.rb b/spec/views/conference/show.html.haml_spec.rb index 28bab522..e1d11cb7 100644 --- a/spec/views/conference/show.html.haml_spec.rb +++ b/spec/views/conference/show.html.haml_spec.rb @@ -8,17 +8,20 @@ describe 'conference/show.html.haml' do description: 'Lorem Ipsum', sponsor_description: 'Lorem Ipsum Dolor', sponsor_email: 'example@example.com', - facebook_url: 'http://www.fbexample.com', - google_url: 'http://www.google-example.com', - instagram_url: "http://instagram.com", - twitter_url: "http://twitter.com", include_registrations_in_splash: true, include_program_in_splash: true, include_sponsors_in_splash: true, - include_social_media_in_splash: true, include_tracks_in_splash: true, include_tickets_in_splash: true, include_banner_in_splash: true) + @conference.contact.update(facebook: 'http://www.fbexample.com', + googleplus: 'http://www.google-example.com', + instagram: 'http://instagram.com', + twitter: 'http://twitter.com', + public: true + ) + @conference.call_for_papers = create(:call_for_papers, conference: @conference, + include_cfp_in_splash: true) @conference.call_for_papers = create(:call_for_papers, conference: @conference, include_cfp_in_splash: true) @conference.sponsorship_levels << create(:sponsorship_level, conference: @conference)