diff --git a/app/assets/images/featured_proposals.jpg b/app/assets/images/featured_proposals.jpg new file mode 100644 index 000000000..303c21747 Binary files /dev/null and b/app/assets/images/featured_proposals.jpg differ diff --git a/app/assets/stylesheets/participation.scss b/app/assets/stylesheets/participation.scss index 1f4bc85f1..7b225b2ff 100644 --- a/app/assets/stylesheets/participation.scss +++ b/app/assets/stylesheets/participation.scss @@ -4,6 +4,7 @@ // 02. New participation // 03. Show participation // 04. List participation +// 05. Featured proposals // // 01. Votes and supports @@ -819,3 +820,156 @@ } } } + +// 05. Featured proposals +// - - - - - - - - - - - - - - - - - - - - - - - - - + +.featured-proposals-container { + background: #FED900; + margin: 0 !important; + + @media (min-width: $medium-breakpoint) { + margin-left: 0 !important; + margin-right: rem-calc(-15) !important; + } + + h2 { + color: $text; + font-size: rem-calc(24); + margin: rem-calc(12) 0 0; + position: relative; + text-transform: uppercase; + + @media (min-width: $medium-breakpoint) { + margin-bottom: rem-calc(27); + } + + .icon-proposals { + font-size: rem-calc(20); + position: absolute; + right: -26px; + top: -5px; + } + } + + .proposals-list { + margin: rem-calc(6) 0; + + @media (min-width: $medium-breakpoint) { + border-left: 1px solid #D2B400; + } + + &:after { + content: none; + position: absolute; + display: block; + border-style: solid; + border-color: #C9AF00 transparent transparent transparent; + bottom: rem-calc(-20); + border-left-width: 0; + border-right-color: transparent; + right: rem-calc(1); + border-width: rem-calc(14) rem-calc(14) 0 0; + + @media (min-width: $medium-breakpoint) { + content: " "; + } + } + } +} + +.proposal-featured { + background: #FED900; + margin-bottom: 0; + margin-top: 0; + padding-left: 0; + + .panel { + background: none; + border: 0; + margin-bottom: 0; + padding: 0 rem-calc(12); + + h3 { + font-weight: bold; + margin: rem-calc(8) 0 0 0; + min-height: auto; + + a { + clear: both; + color: $text; + display: block; + font-size: rem-calc(14); + line-height: $line-height; + text-transform: lowercase; + + &:first-letter { + text-transform: uppercase; + } + } + } + } + + .content { + height: rem-calc(60); + overflow: hidden; + } + + .info { + color: #806C00 !important; + } + + .supports { + @include supports; + background: none; + border: 0; + padding: 0; + padding-left: rem-calc(13); + margin-right: rem-calc(-26); + + &:after { + content: none; + } + + .total-supports { + display: none; + } + + .not-logged, .organizations-votes { + background: #FED900; + line-height: rem-calc(24); + padding-top: rem-calc(6); + } + + .organizations-votes p { + color: $text; + line-height: rem-calc(24); + padding-top: rem-calc(6); + text-align: center; + } + + .button-support { + margin-top: rem-calc(4); + } + + .supported { + margin-top: 0; + } + + .share-supported { + + .social-share-button-twitter, + .social-share-button-facebook, + .social-share-button-google_plus { + height: rem-calc(33); + } + + .social-share-button-twitter:before, + .social-share-button-facebook:before, + .social-share-button-google_plus:before { + font-size: rem-calc(18); + line-height: rem-calc(33); + } + } + } +} diff --git a/app/controllers/concerns/commentable_actions.rb b/app/controllers/concerns/commentable_actions.rb index e98906f04..a6ddf7b57 100644 --- a/app/controllers/concerns/commentable_actions.rb +++ b/app/controllers/concerns/commentable_actions.rb @@ -6,6 +6,7 @@ module CommentableActions @resources = @search_terms.present? ? resource_model.search(@search_terms) : resource_model.all @resources = @resources.tagged_with(@tag_filter) if @tag_filter @resources = @resources.page(params[:page]).for_render.send("sort_by_#{@current_order}") + index_customization if index_customization.present? @tag_cloud = tag_cloud set_resource_votes(@resources) @@ -86,4 +87,8 @@ module CommentableActions def set_resource_votes(instance) send("set_#{resource_name}_votes", instance) end + + def index_customization + nil + end end \ No newline at end of file diff --git a/app/controllers/proposals_controller.rb b/app/controllers/proposals_controller.rb index 14dce9de1..aa91ad02f 100644 --- a/app/controllers/proposals_controller.rb +++ b/app/controllers/proposals_controller.rb @@ -11,11 +11,24 @@ class ProposalsController < ApplicationController load_and_authorize_resource respond_to :html, :js + def index_customization + @featured_proposals = Proposal.all.sort_by_confidence_score.limit(3) if @search_terms.blank? + if @featured_proposals.present? + set_featured_proposal_votes(@featured_proposals) + @resources = @resources.where('proposals.id NOT IN (?)', @featured_proposals.map(&:id)) + end + end + def vote @proposal.register_vote(current_user, 'yes') set_proposal_votes(@proposal) end + def vote_featured + @proposal.register_vote(current_user, 'yes') + set_featured_proposal_votes(@proposal) + end + private def proposal_params @@ -25,4 +38,8 @@ class ProposalsController < ApplicationController def resource_model Proposal end + + def set_featured_proposal_votes(proposals) + @featured_proposals_votes = current_user ? current_user.proposal_votes(proposals) : {} + end end diff --git a/app/models/abilities/common.rb b/app/models/abilities/common.rb index b8b951896..1b3a12f96 100644 --- a/app/models/abilities/common.rb +++ b/app/models/abilities/common.rb @@ -37,6 +37,7 @@ module Abilities if user.level_two_or_three_verified? can :vote, Proposal + can :vote_featured, Proposal end end diff --git a/app/views/proposals/_featured_proposal.html.erb b/app/views/proposals/_featured_proposal.html.erb new file mode 100644 index 000000000..f67a46721 --- /dev/null +++ b/app/views/proposals/_featured_proposal.html.erb @@ -0,0 +1,22 @@ + diff --git a/app/views/proposals/_featured_votes.html.erb b/app/views/proposals/_featured_votes.html.erb new file mode 100644 index 000000000..bda617e96 --- /dev/null +++ b/app/views/proposals/_featured_votes.html.erb @@ -0,0 +1,42 @@ +
+
+ <% if voted_for?(@featured_proposals_votes, proposal) %> +
+ <%= t("proposals.proposal.already_supported") %> +
+ <% else %> + <%= link_to vote_featured_proposal_path(proposal, value: 'yes'), + class: "button button-support tiny radius expand", + title: t('proposals.proposal.support_title'), method: "post", remote: true do %> + <%= t("proposals.proposal.support") %> + <% end %> + <% end %> +
+ + <% if user_signed_in? && current_user.organization? %> + + <% elsif user_signed_in? && !proposal.votable_by?(current_user)%> + + <% elsif !user_signed_in? %> + + <% end %> + + <% if voted_for?(@featured_proposals_votes, proposal) %> +
+ <%= social_share_button_tag(proposal.title, url: proposal_url(proposal), via: "AbriendoMadrid") %> +
+ <% end %> +
\ No newline at end of file diff --git a/app/views/proposals/index.html.erb b/app/views/proposals/index.html.erb index c0bbdc009..77a0a79a0 100644 --- a/app/views/proposals/index.html.erb +++ b/app/views/proposals/index.html.erb @@ -44,6 +44,24 @@ <%= link_to t("proposals.index.start_proposal"), new_proposal_path, class: 'button radius expand' %> + <% if @featured_proposals.present? %> + + <% end %> + <%= render partial: 'proposals/proposal', collection: @proposals %> <%= paginate @proposals %> diff --git a/app/views/proposals/vote_featured.js.erb b/app/views/proposals/vote_featured.js.erb new file mode 100644 index 000000000..52619282b --- /dev/null +++ b/app/views/proposals/vote_featured.js.erb @@ -0,0 +1 @@ +$("#<%= dom_id(@proposal) %>_votes").html('<%= j render("proposals/featured_votes", proposal: @proposal) %>'); \ No newline at end of file diff --git a/config/locales/en.yml b/config/locales/en.yml index bd0a6ce3a..e1af67760 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -155,6 +155,7 @@ en: proposals: index: title: Proposals + featured_proposals_html: "Featured
proposals" start_proposal: Start a proposal select_order: Order by select_order_long: Order proposals by diff --git a/config/locales/es.yml b/config/locales/es.yml index a31572432..ad776b9fe 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -155,6 +155,7 @@ es: proposals: index: title: Propuestas ciudadanas + featured_proposals_html: "Propuestas
destacadas" start_proposal: Crea una propuesta select_order: Ordenar por select_order_long: Estás viendo las propuestas diff --git a/config/routes.rb b/config/routes.rb index 712e835c1..6afbe1f18 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -47,6 +47,7 @@ Rails.application.routes.draw do resources :proposals do member do post :vote + post :vote_featured put :flag put :unflag end diff --git a/spec/features/proposals_spec.rb b/spec/features/proposals_spec.rb index d15ade63b..8706afd42 100644 --- a/spec/features/proposals_spec.rb +++ b/spec/features/proposals_spec.rb @@ -3,10 +3,19 @@ require 'rails_helper' feature 'Proposals' do scenario 'Index' do + featured_proposals = create_featured_proposals proposals = [create(:proposal), create(:proposal), create(:proposal)] visit proposals_path + expect(page).to have_selector('#proposals .proposal-featured', count: 3) + featured_proposals.each do |featured_proposal| + within('#featured-proposals') do + expect(page).to have_content featured_proposal.title + expect(page).to have_css("a[href='#{proposal_path(featured_proposal)}']") + end + end + expect(page).to have_selector('#proposals .proposal', count: 3) proposals.each do |proposal| within('#proposals') do @@ -18,7 +27,7 @@ feature 'Proposals' do scenario 'Paginated Index' do per_page = Kaminari.config.default_per_page - (per_page + 2).times { create(:proposal) } + (per_page + 5).times { create(:proposal) } visit proposals_path @@ -422,6 +431,7 @@ feature 'Proposals' do describe 'Limiting tags shown' do scenario 'Index page shows up to 5 tags per proposal' do + create_featured_proposals tag_list = ["Hacienda", "Economía", "Medio Ambiente", "Corrupción", "Fiestas populares", "Prensa"] create :proposal, tag_list: tag_list @@ -433,6 +443,7 @@ feature 'Proposals' do end scenario 'Index page shows 3 tags with no plus link' do + create_featured_proposals tag_list = ["Medio Ambiente", "Corrupción", "Fiestas populares"] create :proposal, tag_list: tag_list @@ -450,6 +461,8 @@ feature 'Proposals' do feature 'Proposal index order filters' do scenario 'Default order is hot_score', :js do + create_featured_proposals + create(:proposal, title: 'Best proposal').update_column(:hot_score, 10) create(:proposal, title: 'Worst proposal').update_column(:hot_score, 2) create(:proposal, title: 'Medium proposal').update_column(:hot_score, 5) @@ -461,6 +474,8 @@ feature 'Proposals' do end scenario 'Proposals are ordered by confidence_score', :js do + create_featured_proposals + create(:proposal, title: 'Best proposal').update_column(:confidence_score, 10) create(:proposal, title: 'Worst proposal').update_column(:confidence_score, 2) create(:proposal, title: 'Medium proposal').update_column(:confidence_score, 5) @@ -480,6 +495,8 @@ feature 'Proposals' do end scenario 'Proposals are ordered by most commented', :js do + create_featured_proposals + create(:proposal, title: 'Best proposal', comments_count: 10) create(:proposal, title: 'Medium proposal', comments_count: 5) create(:proposal, title: 'Worst proposal', comments_count: 2) @@ -499,6 +516,8 @@ feature 'Proposals' do end scenario 'Proposals are ordered by newest', :js do + create_featured_proposals + create(:proposal, title: 'Best proposal', created_at: Time.now) create(:proposal, title: 'Medium proposal', created_at: Time.now - 1.hour) create(:proposal, title: 'Worst proposal', created_at: Time.now - 1.day) @@ -518,6 +537,8 @@ feature 'Proposals' do end scenario 'Proposals are ordered randomly', :js do + create_featured_proposals + create_list(:proposal, 12) visit proposals_path @@ -616,5 +637,10 @@ feature 'Proposals' do visit proposal_path(proposal) expect(page).to have_content('Deleted user') + + create_featured_proposals + + visit proposals_path + expect(page).to have_content('Deleted user') end end diff --git a/spec/features/votes_spec.rb b/spec/features/votes_spec.rb index 03aaa7e4c..06f7ad4c9 100644 --- a/spec/features/votes_spec.rb +++ b/spec/features/votes_spec.rb @@ -250,10 +250,11 @@ feature 'Votes' do end end - scenario 'Create in index', :js do + scenario 'Create in listed proposal in index', :js do + create_featured_proposals visit proposals_path - within("#proposals") do + within("#proposal_#{@proposal.id}") do find('.in-favor a').click expect(page).to have_content "1 support" @@ -261,6 +262,17 @@ feature 'Votes' do end expect(URI.parse(current_url).path).to eq(proposals_path) end + + scenario 'Create in featured proposal in index', :js do + visit proposals_path + + within("#proposal_#{@proposal.id}") do + find('.in-favor a').click + + expect(page).to have_content "You already supported this proposal, share it!" + end + expect(URI.parse(current_url).path).to eq(proposals_path) + end end end diff --git a/spec/models/abilities/common_spec.rb b/spec/models/abilities/common_spec.rb index f15fb13c1..8e93f5bca 100644 --- a/spec/models/abilities/common_spec.rb +++ b/spec/models/abilities/common_spec.rb @@ -26,6 +26,7 @@ describe "Abilities::Common" do it { should be_able_to(:index, Proposal) } it { should be_able_to(:show, proposal) } it { should_not be_able_to(:vote, Proposal) } + it { should_not be_able_to(:vote_featured, Proposal) } it { should_not be_able_to(:comment_as_administrator, debate) } it { should_not be_able_to(:comment_as_moderator, debate) } @@ -82,11 +83,13 @@ describe "Abilities::Common" do before{ user.update(residence_verified_at: Time.now, confirmed_phone: "1") } it { should be_able_to(:vote, Proposal) } + it { should be_able_to(:vote_featured, Proposal) } end describe "when level 3 verified" do before{ user.update(verified_at: Time.now) } it { should be_able_to(:vote, Proposal) } + it { should be_able_to(:vote_featured, Proposal) } end end diff --git a/spec/support/common_actions.rb b/spec/support/common_actions.rb index b53ff2816..5a3f2d7e5 100644 --- a/spec/support/common_actions.rb +++ b/spec/support/common_actions.rb @@ -161,4 +161,10 @@ module CommonActions expect(page).to have_selector('.in-favor a', visible: false) end + def create_featured_proposals + [create(:proposal, :with_confidence_score, cached_votes_up: 100), + create(:proposal, :with_confidence_score, cached_votes_up: 90), + create(:proposal, :with_confidence_score, cached_votes_up: 80)] + end + end