diff --git a/app/assets/images/star-bright.png b/app/assets/images/star-bright.png new file mode 100644 index 00000000..2dbc8ed3 Binary files /dev/null and b/app/assets/images/star-bright.png differ diff --git a/app/assets/images/star-glow.png b/app/assets/images/star-glow.png new file mode 100644 index 00000000..b605587a Binary files /dev/null and b/app/assets/images/star-glow.png differ diff --git a/app/assets/images/star.png b/app/assets/images/star.png new file mode 100644 index 00000000..db7e5596 Binary files /dev/null and b/app/assets/images/star.png differ diff --git a/app/assets/javascripts/osem.js b/app/assets/javascripts/osem.js index 21dd66c8..dbae93ac 100644 --- a/app/assets/javascripts/osem.js +++ b/app/assets/javascripts/osem.js @@ -60,6 +60,11 @@ $(function() { $(".comment-reply").hide(); $(".user-details-popover").popover(); $("#comments-div").hide(); + + $("#votes-link").click(function(){ + $("#votes-div").toggle(); + return false; + }); }); function word_count(text, divId, maxcount) { diff --git a/app/assets/stylesheets/osem.css b/app/assets/stylesheets/osem.css index a767ed11..81531f5e 100644 --- a/app/assets/stylesheets/osem.css +++ b/app/assets/stylesheets/osem.css @@ -5,6 +5,23 @@ height: 100%; /* The html and body elements cannot have any padding or margin. */ } +/* Styling for voting on proposals*/ +.myrating.bright { background-image: url(../assets/star-bright.png); } +.myrating.glow { background-image: url(../assets/star-glow.png); } +.othersrating.bright { background-image: url(../assets/star-bright.png); } +.avgrating.bright { background-image: url(../assets/star-bright.png); } +.avgrating { + background: url(../assets/star.png) 0 0; + width: 26px; + height: 26px; + display: block; +} +.myrating, .othersrating { + background: url(../assets/star.png) 0 0; + width: 26px; + height: 26px; + float: left; +} /* Wrapper for page content to push down footer */ #wrap { diff --git a/app/controllers/admin/events_controller.rb b/app/controllers/admin/events_controller.rb index f15d232f..a9f3de5c 100644 --- a/app/controllers/admin/events_controller.rb +++ b/app/controllers/admin/events_controller.rb @@ -26,6 +26,7 @@ class Admin::EventsController < ApplicationController @event_types = @conference.event_types @comments = @event.root_comments @comment_count = @event.comment_threads.count + @ratings = @event.votes.includes(:person) end def edit @@ -76,4 +77,18 @@ class Admin::EventsController < ApplicationController expire_page :controller => '/schedule', :action => :index redirect_to(admin_conference_events_path(:conference_id => @conference.short_title), :notice => "Updated state") end + + def vote + event = Event.find(params[:id]) + + if votes = current_user.person.votes.find_by_event_id(params[:id]) + votes.update_attributes(:rating => params[:rating]) + else + @myvote = event.votes.build + @myvote.person = current_user.person + @myvote.rating = params[:rating] + @myvote.save + end + redirect_to admin_conference_event_path(@conference.short_title, event) + end end diff --git a/app/models/call_for_papers.rb b/app/models/call_for_papers.rb index 6dcef8d7..f3915b75 100644 --- a/app/models/call_for_papers.rb +++ b/app/models/call_for_papers.rb @@ -1,7 +1,8 @@ class CallForPapers < ActiveRecord::Base - attr_accessible :start_date, :end_date, :hard_deadline, :description, :schedule_changes + attr_accessible :start_date, :end_date, :hard_deadline, :description, :schedule_changes, :rating, :rating_desc belongs_to :conference validates_presence_of :start_date, :end_date, :hard_deadline + validates :rating, :numericality => { :greater_than_or_equal_to => 1, :less_than_or_equal_to => 10 } -end \ No newline at end of file +end diff --git a/app/models/event.rb b/app/models/event.rb index c735cfb7..b5aafd29 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -9,8 +9,10 @@ class Event < ActiveRecord::Base has_many :event_attachments, :dependent => :destroy has_many :people, :through => :event_people has_many :speakers, :through => :event_people, :source => :person, :conditions => {"event_people.event_role" => "speaker"} + has_many :votes + has_many :voters, :through => :votes, :source => :person belongs_to :event_type - + has_and_belongs_to_many :registrations belongs_to :track @@ -62,6 +64,19 @@ class Event < ActiveRecord::Base end end + def voted?(event, person) + event.votes.where("person_id = ?", person).first + end + + def average_rating + @total_rating = 0 + self.votes.each do |vote| + @total_rating = @total_rating + vote.rating + end + @total = self.votes.size + number_with_precision(@total_rating / @total.to_f, :precision => 2, :strip_insignificant_zeros => true) + end + def submitter result = self.event_people.where(:event_role => "submitter").first if !result.nil? diff --git a/app/models/person.rb b/app/models/person.rb index ea61ef2c..a149bf23 100644 --- a/app/models/person.rb +++ b/app/models/person.rb @@ -8,6 +8,8 @@ class Person < ActiveRecord::Base has_many :event_people, :dependent => :destroy has_many :events, :through => :event_people, :uniq => true has_many :registrations, :dependent => :destroy + has_many :votes, :dependent => :destroy + has_many :voted_events, :through => :votes, :source => :events validates :first_name, :presence => true validates :last_name, :presence => true diff --git a/app/models/vote.rb b/app/models/vote.rb new file mode 100644 index 00000000..051561ae --- /dev/null +++ b/app/models/vote.rb @@ -0,0 +1,10 @@ +class Vote < ActiveRecord::Base + attr_accessible :rating + + belongs_to :person + belongs_to :event + + delegate :first_name, :to => :person + delegate :last_name, :to => :person + delegate :public_name, :to => :person +end \ No newline at end of file diff --git a/app/views/admin/callforpapers/show.html.haml b/app/views/admin/callforpapers/show.html.haml index dac989de..6757dff7 100644 --- a/app/views/admin/callforpapers/show.html.haml +++ b/app/views/admin/callforpapers/show.html.haml @@ -9,4 +9,6 @@ = f.input :hard_deadline, :as => :string, :input_html => { :id => "cfp-hard-datepicker", :readonly => "readonly" } = f.input :description, :hint => "Welcome text for the Call for Papers" = f.input :schedule_changes - = f.action :submit, :as => :button, :button_html => {:class => "btn btn-primary"} \ No newline at end of file + = f.input :rating, :hint => "Enter the number of different rating levels you want to have for voting on proposals." + = f.input :rating_desc, :label => "Rating Description", :hint => "Enter comments about voting process.", :input_html => {:value => "1 is for 'I don't like this proposal',\n2 is for 'I am ok with this proposal.',\n3 is for 'I love this proposal!'", :rows => 5, :class => "span6"} + = f.action :submit, :as => :button, :button_html => {:class => "btn btn-primary"} diff --git a/app/views/admin/events/_proposal.html.haml b/app/views/admin/events/_proposal.html.haml index cc2fb7c0..0248ec3c 100644 --- a/app/views/admin/events/_proposal.html.haml +++ b/app/views/admin/events/_proposal.html.haml @@ -142,7 +142,11 @@ %td = link_to "Delete", conference_proposal_event_attachment_path(@conference.short_title, @event.id, a.id), :method => :delete, :confirm => "Are you sure you want to delete this attachment? It's permanant!" - +- if @conference.call_for_papers.rating + .row-fluid + = link_to "Votes (#{@event.voters.length})", "#", :id => "votes-link" + #votes-div + = render :partial => 'voting' .row-fluid = link_to "Comments (#{@comment_count})", "#", :id => "event-comment-link" #comments-div @@ -156,4 +160,4 @@ %br - @comments.each do |comment| %div - = raw format_comments(comment) + = raw format_comments(comment) \ No newline at end of file diff --git a/app/views/admin/events/_voting.html.haml b/app/views/admin/events/_voting.html.haml new file mode 100644 index 00000000..11ed1eed --- /dev/null +++ b/app/views/admin/events/_voting.html.haml @@ -0,0 +1,47 @@ +%table#myeventratings{:style=>"width: 20%"} + %tr + %td + %b Your vote: + %td + - @conference.call_for_papers.rating.times do |counter| + - voted = @event.voted?(@event, current_user.person) + - if voted && voted.rating == counter+1 + = link_to "", vote_admin_conference_event_path(@conference.short_title, @event, :rating => counter+1), :remote => true, :id =>"label#{counter+1}", :class => "myrating", :voted => true + - else + = link_to "", vote_admin_conference_event_path(@conference.short_title, @event, :rating => counter+1), :remote => true, :id =>"label#{counter+1}", :class => "myrating" + %br + + - if @ratings.length > 0 + - @ratings.each do |rate| + - unless rate.person_id == current_user.person.id + %tr + %td + = rate.first_name + = rate.last_name + %td + - @conference.call_for_papers.rating.times do |counter| + - voted = @event.voted?(@event, rate.person) + - if voted && voted.rating == counter+1 + = label_tag "label#{counter+1}", "", :class => "othersrating", :voted => true + = javascript_tag "$('label[voted=true]').prevAll().andSelf().addClass('bright');" + - else + = label_tag "label#{counter+1}", "", :class => "othersrating" +:javascript + $(function () { + var checkedId = $("a[voted='true']").attr('id'); + $('a[id=' + checkedId + ']').prevAll().andSelf().addClass('bright'); + }); + + $(".myrating").hover( + function() { // mouseover + $(this).prevAll().andSelf().addClass('glow'); + }, + function() { // mouseout + $(this).siblings().andSelf().removeClass('glow'); + } + ); + + $(".myrating").click(function() { + $(this).siblings().removeClass("bright"); + $(this).prevAll().andSelf().addClass("bright"); + }); \ No newline at end of file diff --git a/app/views/admin/events/index.html.haml b/app/views/admin/events/index.html.haml index eafc6af1..c37d3906 100644 --- a/app/views/admin/events/index.html.haml +++ b/app/views/admin/events/index.html.haml @@ -99,6 +99,8 @@ %b ID %th %b Title + %th + %b Rating %th %b Submitter %th @@ -115,6 +117,21 @@ = event.id %td =link_to event.title, admin_conference_event_path(@conference.short_title, event) + %td + - if @conference.call_for_papers.rating + - if event.average_rating.to_f > 0 + Rating: (#{event.average_rating}/#{@conference.call_for_papers.rating}) + - else + Rating: (0/#{@conference.call_for_papers.rating}) + %br + + - @conference.call_for_papers.rating.times do |counter| + - if event.average_rating.to_f.round == counter+1 + = label_tag "label_rating", "", :class => "avgrating", :avgrate => true + = javascript_tag "$('label[avgrate=true]').prevAll().andSelf().addClass('bright');" + - else + = label_tag "label_rating", "", :class => "avgrating" + - if event.submitter.registrations.count < 1 - bgcolor="#F7819F" - else diff --git a/app/views/admin/events/vote.js.erb b/app/views/admin/events/vote.js.erb new file mode 100644 index 00000000..38ffd622 --- /dev/null +++ b/app/views/admin/events/vote.js.erb @@ -0,0 +1 @@ +$('table#myeventratings').replaceWith("<%= escape_javascript(render :partial => 'voting') %>"); \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 0cbeab15..a5451c60 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -40,6 +40,7 @@ Osem::Application.routes.draw do post :comment put :update_state put :update_track + get :vote end resource :speaker, :only => [:edit, :update] end diff --git a/db/migrate/20130815085420_create_votes.rb b/db/migrate/20130815085420_create_votes.rb new file mode 100644 index 00000000..1b4460a7 --- /dev/null +++ b/db/migrate/20130815085420_create_votes.rb @@ -0,0 +1,15 @@ +class CreateVotes < ActiveRecord::Migration + def up + create_table :votes do |t| + t.references :person + t.references :event + t.integer :rating + + t.timestamps + end + end + + def down + drop_table :votes + end +end diff --git a/db/migrate/20130815201317_add_rating_to_call_for_papers.rb b/db/migrate/20130815201317_add_rating_to_call_for_papers.rb new file mode 100644 index 00000000..234ba63d --- /dev/null +++ b/db/migrate/20130815201317_add_rating_to_call_for_papers.rb @@ -0,0 +1,5 @@ +class AddRatingToCallForPapers < ActiveRecord::Migration + def change + add_column :call_for_papers, :rating, :integer, :null => 1 + end +end diff --git a/db/migrate/20130815201511_add_rating_desc_to_call_for_papers.rb b/db/migrate/20130815201511_add_rating_desc_to_call_for_papers.rb new file mode 100644 index 00000000..386a3064 --- /dev/null +++ b/db/migrate/20130815201511_add_rating_desc_to_call_for_papers.rb @@ -0,0 +1,5 @@ +class AddRatingDescToCallForPapers < ActiveRecord::Migration + def change + add_column :call_for_papers, :rating_desc, :text + end +end