diff --git a/.gitignore b/.gitignore index 75fe283a..2a4f41ce 100755 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ client/js/nonprofits/donate/plugins-enabled .DS_Store +/postgres-data # Ignore bundler config /.bundle @@ -62,4 +63,4 @@ javascripts/api !public/css/donate-button.css !public/css/donate-button.v2.css !public/svgs -!public/svgs/* \ No newline at end of file +!public/svgs/* diff --git a/Gemfile b/Gemfile index 88b0285c..ed134f19 100755 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ source 'https://rubygems.org' -ruby '2.3.6' +ruby '~> 2.3.6' gem 'rake' gem 'rails', '3.2.22.5' gem 'rails_12factor' @@ -27,7 +27,7 @@ gem 'hamster' gem 'aws-ses' gem 'aws-sdk' - + # for blocking ip addressses gem 'rack-attack' diff --git a/app/assets/stylesheets/campaigns/common.css.scss b/app/assets/stylesheets/campaigns/common.css.scss new file mode 100644 index 00000000..accf7b7c --- /dev/null +++ b/app/assets/stylesheets/campaigns/common.css.scss @@ -0,0 +1,9 @@ +/* License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later */ + +body .campaign-banner { + margin: auto; + width: 980px; + max-height: 120px; + text-align: center; + overflow: hidden; +} \ No newline at end of file diff --git a/app/assets/stylesheets/campaigns/peer_to_peer/page.css.scss b/app/assets/stylesheets/campaigns/peer_to_peer/page.css.scss index 76fb21a7..826971ee 100644 --- a/app/assets/stylesheets/campaigns/peer_to_peer/page.css.scss +++ b/app/assets/stylesheets/campaigns/peer_to_peer/page.css.scss @@ -6,11 +6,14 @@ @import 'components/simple_tabs'; @import 'pikaday'; @import 'common/image_uploader'; +@import '../common'; body { padding: 0; background: $fog; } + + main { display: block; padding: 60px 0 50px 0; diff --git a/app/assets/stylesheets/campaigns/show/page.css.scss b/app/assets/stylesheets/campaigns/show/page.css.scss index 53e60010..2ae85615 100644 --- a/app/assets/stylesheets/campaigns/show/page.css.scss +++ b/app/assets/stylesheets/campaigns/show/page.css.scss @@ -13,6 +13,7 @@ @import 'components/draggable'; @import 'gift_levels'; @import '../../nonprofits/donation_form/form'; +@import '../common'; .button--gift { font-size: 17px; @@ -103,6 +104,43 @@ margin-right: 1px; } +.campaigner-profile { + display: flex; + flex-wrap: nowrap; + align-items: baseline; +} + +.campaigner-profile > figure { + display: flex; + flex-direction: column; + align-items: center; + margin: auto 10px; + align-self: flex-start; +} + +.campaigner-profile > figure > .avatar { + flex-basis: 20%; + min-width: 100px; + height: auto; +} + +.avatar > img { + clip-path: circle(50% at center); +} + +.campaigner-profile > figure > figcaption { + flex-basis: 40%; + padding: 15px; + text-align: left; +} + +.campaigner-profile .reason { + flex-basis: 60%; +} + +.campaigner-profile .pastelBox-body { + min-height: 100px; +} @media screen and (max-width: 1000px) { .box, diff --git a/app/assets/stylesheets/common/image_uploader.css.scss b/app/assets/stylesheets/common/image_uploader.css.scss index 7956c881..be673d96 100644 --- a/app/assets/stylesheets/common/image_uploader.css.scss +++ b/app/assets/stylesheets/common/image_uploader.css.scss @@ -19,6 +19,11 @@ width: 192px; } +.image-upload--banner { + width: 100%; + height: auto; +} + .image-upload span { margin-top: 30px; padding: 5px; @@ -28,6 +33,11 @@ @include basicShadow; } +.image-upload--banner span { + margin-top: 30px; + margin-bottom: 30px; +} + .image-upload--large span { margin-top: 60px; } diff --git a/app/controllers/campaigns_controller.rb b/app/controllers/campaigns_controller.rb index 21c57919..37d15dc3 100644 --- a/app/controllers/campaigns_controller.rb +++ b/app/controllers/campaigns_controller.rb @@ -5,6 +5,7 @@ class CampaignsController < ApplicationController helper_method :current_campaign_editor? before_filter :authenticate_confirmed_user!, only: [:create, :name_and_id, :duplicate] before_filter :authenticate_campaign_editor!, only: [:update, :soft_delete] + before_filter :authenticate_nonprofit_user!, only: [:create_via_template] before_filter :check_nonprofit_status, only: [:index, :show] def index @@ -36,23 +37,34 @@ class CampaignsController < ApplicationController @nonprofit = current_nonprofit @url = Format::Url.concat(root_url, @campaign.url) - @campaign_background_image = FetchBackgroundImage.with_model(@campaign) - - respond_to do |format| - format.html + if @campaign.child_campaign? + @parent_campaign = @campaign.parent_campaign + @peer_to_peer_campaign_param = @parent_campaign.id + else + @peer_to_peer_campaign_param = @campaign.id end + + @campaign_background_image = FetchBackgroundImage.with_model(@campaign) end def activities - render json: QueryDonations.for_campaign_activities(params[:id]) + @campaign = current_campaign + render json: QueryDonations.for_campaign_activities(@campaign.id) end def create Time.use_zone(current_nonprofit.timezone || 'UTC') do params[:campaign][:end_datetime] = Chronic.parse(params[:campaign][:end_datetime]) if params[:campaign][:end_datetime].present? end - campaign = current_nonprofit.campaigns.create params[:campaign] - json_saved campaign, 'Campaign created! Well done.' + + if !params[:campaign][:parent_campaign_id] + campaign = current_nonprofit.campaigns.create params[:campaign] + json_saved campaign, 'Campaign created! Well done.' + else + profile_id = params[:campaign][:profile_id] + Profile.find(profile_id).update_attributes params[:profile] + render json: CreatePeerToPeerCampaign.create(params[:campaign], profile_id) + end end def update @@ -63,7 +75,6 @@ class CampaignsController < ApplicationController json_saved current_campaign, 'Successfully updated!' end - # post 'nonprofits/:np_id/campaigns/:campaign_id/duplicate' def duplicate @@ -98,7 +109,22 @@ class CampaignsController < ApplicationController def peer_to_peer session[:donor_signup_url] = request.env["REQUEST_URI"] - @npo = Nonprofit.find_by_id(params[:npo_id]) + @nonprofit = Nonprofit.find_by_id(params[:npo_id]) + @parent_campaign = Campaign.find_by_id(params[:campaign_id]) + + if params[:campaign_id].present? && !@parent_campaign + raise ActionController::RoutingError.new('Not Found') + end + + if current_user + @profile = current_user.profile + if (@parent_campaign) + @child_campaign = Campaign.where( + profile_id: @profile.id, + parent_campaign_id: @parent_campaign.id + ).first + end + end end private @@ -108,5 +134,4 @@ class CampaignsController < ApplicationController raise ActionController::RoutingError.new('Not Found') end end - end diff --git a/app/models/campaign.rb b/app/models/campaign.rb index f19278a4..d532a312 100644 --- a/app/models/campaign.rb +++ b/app/models/campaign.rb @@ -13,6 +13,8 @@ class Campaign < ActiveRecord::Base :remove_main_image, # for carrierwave :background_image, :remove_background_image, #bool carrierwave + :banner_image, + :remove_banner_image, :published, :video_url, #str :vimeo_video_id, @@ -30,7 +32,10 @@ class Campaign < ActiveRecord::Base :hide_thermometer, #bool :hide_title, # bool :receipt_message, # text - :hide_custom_amounts # boolean + :hide_custom_amounts, # boolean + :parent_campaign_id, + :reason_for_supporting, + :default_reason_for_supporting validate :end_datetime_cannot_be_in_past, :on => :create validates :profile, :presence => true @@ -47,6 +52,7 @@ class Campaign < ActiveRecord::Base mount_uploader :main_image, CampaignMainImageUploader mount_uploader :background_image, CampaignBackgroundImageUploader + mount_uploader :banner_image, CampaignBannerImageUploader has_many :donations has_many :charges, through: :donations @@ -61,6 +67,9 @@ class Campaign < ActiveRecord::Base belongs_to :profile belongs_to :nonprofit + belongs_to :parent_campaign, class_name: 'Campaign' + has_many :children_campaigns, class_name: 'Campaign', foreign_key: 'parent_campaign_id' + scope :published, -> {where(:published => true)} scope :active, -> {where(:published => true).where("end_datetime IS NULL OR end_datetime >= ?", Date.today)} scope :past, -> {where(:published => true).where("end_datetime < ?", Date.today)} @@ -155,4 +164,21 @@ class Campaign < ActiveRecord::Base (self.end_datetime.to_date - Date.today).to_i end + + def child_params + excluded_for_peer_to_peer = %w( + id created_at updated_at slug profile_id url + total_raised show_recurring_amount external_identifier parent_campaign_id + reason_for_supporting metadata + ) + attributes.except(*excluded_for_peer_to_peer) + end + + def child_campaign? + parent_campaign.present? + end + + def parent_campaign? + !child_campaign? + end end diff --git a/app/uploaders/campaign_banner_image_uploader.rb b/app/uploaders/campaign_banner_image_uploader.rb new file mode 100644 index 00000000..1c4010d7 --- /dev/null +++ b/app/uploaders/campaign_banner_image_uploader.rb @@ -0,0 +1,16 @@ +# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later +class CampaignBannerImageUploader < CarrierWave::Uploader::Base + include CarrierWave::MiniMagick + + def store_dir + "uploads/campaigns/#{mounted_as}/#{model.id}" + end + + def extension_white_list + %w(jpg jpeg png) + end + + def cache_dir + "#{Rails.root}/tmp/uploads" + end +end diff --git a/app/views/campaigns/_admin_top_nav.html.erb b/app/views/campaigns/_admin_top_nav.html.erb index 6f1499e3..0ee237a4 100644 --- a/app/views/campaigns/_admin_top_nav.html.erb +++ b/app/views/campaigns/_admin_top_nav.html.erb @@ -5,39 +5,42 @@
Manage Campaign
- - - - Settings - - - - Dashboard - - - - - Offsite Donation - - - - Gift Options + + Settings - - - Custom Receipt - + <% if @campaign.parent_campaign? %> + + Dashboard + + + + + Offsite Donation + + + + + Gift Options + + + + + Custom Receipt + + <% end %> Preview Mode - - - Copy Campaign - + <% if @campaign.parent_campaign? %> + + + Copy Campaign + + <% end %> <%= render 'components/messages/deleted_campaign_or_event', type: 'campaign' %> diff --git a/app/views/campaigns/_campaigns_table.html.erb b/app/views/campaigns/_campaigns_table.html.erb index 02168fd0..d2ead6ad 100644 --- a/app/views/campaigns/_campaigns_table.html.erb +++ b/app/views/campaigns/_campaigns_table.html.erb @@ -1,6 +1,8 @@ <%- # License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later -%>@@ -18,11 +20,11 @@ <%= campaign.summary ? strip_tags(campaign.summary) : strip_tags(campaign.tagline) %> <% if campaign.show_total_count %> - <%= campaign.donations.count %> supporters + <%= metric['supporters_count'] %> supporters <% end %> <% if campaign.show_total_raised %> - <%= print_currency campaign.total_raised, campaign.nonprofit.currency_symbol %> raised + <%= print_currency metric['total_raised'], campaign.nonprofit.currency_symbol %> raised <% end %> | diff --git a/app/views/campaigns/_new_peer_to_peer_modal.html.erb b/app/views/campaigns/_new_peer_to_peer_modal.html.erb new file mode 100644 index 00000000..7e3e0df2 --- /dev/null +++ b/app/views/campaigns/_new_peer_to_peer_modal.html.erb @@ -0,0 +1,77 @@ + + + +