Self-serve sponsorship options (#3371)
* WIP - Initial work on sponsorship landing page * Add initial partnership page
This commit is contained in:
parent
22e76bee84
commit
4ebfcd8bc0
31 changed files with 952 additions and 29 deletions
|
|
@ -1121,6 +1121,23 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
.sidebar-sponsorship-level {
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
width: calc(100% - 6px);
|
||||
padding: 26px 0px;
|
||||
border-radius: 3px;
|
||||
margin-bottom: 10px;
|
||||
font-family: $helvetica-condensed;
|
||||
font-stretch: condensed;
|
||||
font-size: 1.1em;
|
||||
@include themeable(
|
||||
border,
|
||||
theme-container-border,
|
||||
1px solid $outline-color
|
||||
);
|
||||
@include themeable(box-shadow, theme-container-box-shadow, $bold-shadow);
|
||||
}
|
||||
.widget {
|
||||
width: calc(100% - 30px);
|
||||
padding: 10px 12px;
|
||||
|
|
|
|||
192
app/assets/stylesheets/partnerships.scss
Normal file
192
app/assets/stylesheets/partnerships.scss
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
@import 'variables';
|
||||
@import 'mixins';
|
||||
|
||||
.partnerships-container {
|
||||
width: 800px;
|
||||
max-width: 96%;
|
||||
margin: 100px auto;
|
||||
&.partnerships-container-show {
|
||||
h1 {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
h1 {
|
||||
text-align: center;
|
||||
font-size: 2.5em;
|
||||
padding: 1em 0;
|
||||
img {
|
||||
height: 2.2em;
|
||||
width: 2.2em;
|
||||
transform: rotate(6deg);
|
||||
border-radius: 0.2em;
|
||||
vertical-align: -0.7em;
|
||||
margin-left: 0.3em;
|
||||
}
|
||||
}
|
||||
.partner-credits-explainer {
|
||||
@include themeable(
|
||||
background,
|
||||
theme-container-background,
|
||||
$white
|
||||
);
|
||||
box-sizing: border-box;
|
||||
padding: 25px 20px 30px;
|
||||
border-radius: 12px;
|
||||
margin: 50px auto 40px;
|
||||
width: calc(100% - 20px);
|
||||
@include themeable(
|
||||
border,
|
||||
theme-border,
|
||||
1px solid $light-medium-gray
|
||||
);
|
||||
@include themeable(
|
||||
box-shadow,
|
||||
theme-container-box-shadow,
|
||||
2px 2px 8px darken($light-medium-gray, 5%)
|
||||
);
|
||||
.partner-explainer-notice {
|
||||
padding: 15px;
|
||||
margin: 25px 0px 12px;
|
||||
border-radius: 3px;
|
||||
font-weight: bold;
|
||||
@include themeable(
|
||||
background,
|
||||
theme-container-accent-background,
|
||||
$light-gray
|
||||
);
|
||||
}
|
||||
h4 {
|
||||
font-size: 0.8em;
|
||||
margin: 3px 0px;
|
||||
@include themeable(
|
||||
color,
|
||||
theme-secondary-color,
|
||||
$medium-gray
|
||||
);
|
||||
}
|
||||
h3 {
|
||||
margin: 5px 0px;
|
||||
font-size: 1.8em;
|
||||
@include themeable(
|
||||
color,
|
||||
theme-color,
|
||||
#131a38
|
||||
);
|
||||
img {
|
||||
height: 1.2em;
|
||||
width: 1.2em;
|
||||
vertical-align: -0.25em;
|
||||
border-radius: 100px;
|
||||
margin-right: 0.3em;
|
||||
}
|
||||
}
|
||||
select {
|
||||
display: block;
|
||||
font-size: 1.3em;
|
||||
}
|
||||
textarea {
|
||||
width: 80%;
|
||||
font-size: 1em;
|
||||
padding: 0.5em;
|
||||
border-radius: 3px;
|
||||
display: block;
|
||||
height: 300px;
|
||||
@include themeable(
|
||||
border,
|
||||
theme-container-border,
|
||||
1px solid $light-medium-gray
|
||||
);
|
||||
}
|
||||
input {
|
||||
width: 50%;
|
||||
font-size: 1.3em;
|
||||
padding: 0.5em;
|
||||
border-radius: 3px;
|
||||
display: block;
|
||||
@include themeable(
|
||||
border,
|
||||
theme-container-border,
|
||||
1px solid $light-medium-gray
|
||||
);
|
||||
}
|
||||
a, button {
|
||||
padding: 5px 20px;
|
||||
font-size: 1.5em;
|
||||
border-radius: 8px;
|
||||
font-weight: bold;
|
||||
margin: 8px 0px;
|
||||
display: inline-block;
|
||||
border: 0px;
|
||||
@include themeable(
|
||||
background,
|
||||
theme-anchor-color,
|
||||
$bold-blue
|
||||
);
|
||||
@include themeable(
|
||||
color,
|
||||
theme-container-background,
|
||||
white
|
||||
);
|
||||
}
|
||||
}
|
||||
.partnership-options {
|
||||
margin: 40px 0px;
|
||||
}
|
||||
.partnership-option-card {
|
||||
@include themeable(
|
||||
background,
|
||||
theme-container-background,
|
||||
$white
|
||||
);
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
@media screen and ( min-width: 820px ){
|
||||
width: calc(50% - 15px);
|
||||
margin-right: 8px;
|
||||
ul {
|
||||
height: 220px;
|
||||
}
|
||||
}
|
||||
box-sizing: border-box;
|
||||
padding: 15px;
|
||||
border-radius: 12px;
|
||||
margin: 10px 0px;
|
||||
display: inline-block;
|
||||
@include themeable(
|
||||
border,
|
||||
theme-border,
|
||||
1px solid $light-medium-gray
|
||||
);
|
||||
@include themeable(
|
||||
box-shadow,
|
||||
theme-container-box-shadow,
|
||||
2px 2px 8px darken($light-medium-gray, 5%)
|
||||
);
|
||||
li {
|
||||
padding: 8px 0px;
|
||||
}
|
||||
h2 {
|
||||
margin: 0px;
|
||||
padding: 10px 0px;
|
||||
border-bottom: 2px solid rgba(0,0,0,0.1);
|
||||
}
|
||||
.partnership-option-cta {
|
||||
display: block;
|
||||
font-size: 1.6em;
|
||||
padding: 20px 0px;
|
||||
text-align: center;
|
||||
border-radius: 5px;
|
||||
font-weight: bold;
|
||||
@include themeable(
|
||||
background,
|
||||
theme-anchor-color,
|
||||
$bold-blue
|
||||
);
|
||||
@include themeable(
|
||||
color,
|
||||
theme-container-background,
|
||||
white
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
104
app/controllers/partnerships_controller.rb
Normal file
104
app/controllers/partnerships_controller.rb
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
class PartnershipsController < ApplicationController
|
||||
before_action :set_cache_control_headers, only: %i[index]
|
||||
before_action :authenticate_user!, only: %i[create]
|
||||
after_action :verify_authorized
|
||||
|
||||
def index
|
||||
skip_authorization
|
||||
set_surrogate_key_header "partnership-index"
|
||||
end
|
||||
|
||||
def show
|
||||
skip_authorization
|
||||
end
|
||||
|
||||
def create
|
||||
@level = params[:sponsorship_level]
|
||||
@number_of_credits_needed = credits_for_level
|
||||
@organization = Organization.find(params[:organization_id])
|
||||
update_sponsorship_instructions
|
||||
authorize @organization, :admin_of_org?
|
||||
@available_org_credits = @organization.credits.where(spent: false)
|
||||
if @level == "tag"
|
||||
@tag = Tag.find_by(name: params[:tag_name])
|
||||
@tag.sponsor_organization_id = @organization.id
|
||||
slackbot_ping("@#{current_user.username} bought a ##{@tag.name} sponsorship for @#{@organization.username}")
|
||||
if @available_org_credits.size >= @number_of_credits_needed
|
||||
@tag.save!
|
||||
spend_credits
|
||||
redirect_back(fallback_location: "/partnerships")
|
||||
else
|
||||
raise "Not enough credits"
|
||||
end
|
||||
elsif @level == "media"
|
||||
# For now. Just ping slack.
|
||||
slackbot_ping("📹 @#{current_user.username} bought #{@number_of_credits_needed} media credits for @#{@organization.username}")
|
||||
if @available_org_credits.size >= @number_of_credits_needed
|
||||
spend_credits
|
||||
redirect_back(fallback_location: "/partnerships")
|
||||
end
|
||||
elsif @level == "editorial"
|
||||
SlackBot.ping(
|
||||
message: "@#{current_user.username} bought #{@number_of_credits_needed} credits for @#{@organization.username}",
|
||||
channel: "incoming-partners",
|
||||
username: "media_sponsor",
|
||||
icon_emoji: ":partyparrot:",
|
||||
)
|
||||
slackbot_ping("✍ @#{current_user.username} bought an editorial partnership for @#{@organization.username}")
|
||||
if @available_org_credits.size >= @number_of_credits_needed
|
||||
spend_credits
|
||||
redirect_back(fallback_location: "/partnerships")
|
||||
end
|
||||
else
|
||||
@organization.sponsorship_level = @level
|
||||
@organization.sponsorship_status = "pending"
|
||||
@organization.sponsorship_expires_at = (@organization.sponsorship_expires_at || Time.current) + 1.month
|
||||
slackbot_ping("@#{current_user.username} bought a #{@level} sponsorship for @#{@organization.username}")
|
||||
if @available_org_credits.size >= @number_of_credits_needed
|
||||
@organization.save!
|
||||
spend_credits
|
||||
redirect_back(fallback_location: "/partnerships")
|
||||
else
|
||||
raise "Not enough credits"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def credits_for_level
|
||||
if @level == "gold"
|
||||
6000
|
||||
elsif @level == "silver"
|
||||
300
|
||||
elsif @level == "tag"
|
||||
500
|
||||
elsif @level == "bronze"
|
||||
50
|
||||
elsif @level == "editorial"
|
||||
500
|
||||
elsif @level == "media"
|
||||
params[:sponsorship_amount].to_i
|
||||
else
|
||||
raise "Invalid level"
|
||||
end
|
||||
end
|
||||
|
||||
def update_sponsorship_instructions
|
||||
@organization.sponsorship_instructions = @organization.sponsorship_instructions + "\n---\n#{Time.current}\n---\n" + params[:sponsorship_instructions].to_s
|
||||
@organization.sponsorship_instructions_updated_at = Time.current
|
||||
end
|
||||
|
||||
def spend_credits
|
||||
@available_org_credits.limit(@number_of_credits_needed).update_all(spent: true)
|
||||
end
|
||||
|
||||
def slackbot_ping(text)
|
||||
SlackBot.ping(
|
||||
message: text,
|
||||
channel: "incoming-partners",
|
||||
username: "media_sponsor",
|
||||
icon_emoji: ":partyparrot:",
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
@ -37,7 +37,9 @@ class OrganizationDashboard < Administrate::BaseDashboard
|
|||
cta_body_markdown: Field::Text,
|
||||
sponsorship_url: Field::Text,
|
||||
sponsorship_tagline: Field::Text,
|
||||
is_gold_sponsor: Field::Boolean,
|
||||
sponsorship_status: Field::Text,
|
||||
sponsorship_level: Field::Text,
|
||||
sponsorship_instructions: Field::Text,
|
||||
sponsorship_blurb_html: Field::Text,
|
||||
sponsorship_featured_number: Field::Number
|
||||
}.freeze
|
||||
|
|
@ -89,7 +91,8 @@ class OrganizationDashboard < Administrate::BaseDashboard
|
|||
sponsorship_url
|
||||
sponsorship_tagline
|
||||
sponsorship_blurb_html
|
||||
is_gold_sponsor
|
||||
sponsorship_level
|
||||
sponsorship_status
|
||||
sponsorship_featured_number
|
||||
].freeze
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ class TagDashboard < Administrate::BaseDashboard
|
|||
pretty_name: Field::String,
|
||||
profile_image: CarrierwaveField,
|
||||
social_image: CarrierwaveField,
|
||||
sponsorship_organization_id: Field::Number,
|
||||
sponsorship_status: Field::String,
|
||||
bg_color_hex: Field::String,
|
||||
text_color_hex: Field::String,
|
||||
keywords_for_search: Field::String,
|
||||
|
|
@ -81,6 +83,8 @@ class TagDashboard < Administrate::BaseDashboard
|
|||
social_image
|
||||
bg_color_hex
|
||||
text_color_hex
|
||||
sponsorship_organization_id
|
||||
sponsorship_status
|
||||
keywords_for_search
|
||||
buffer_profile_id_code
|
||||
].freeze
|
||||
|
|
|
|||
|
|
@ -25,4 +25,11 @@ class OrganizationDecorator < ApplicationDecorator
|
|||
text: "#ffffff"
|
||||
}
|
||||
end
|
||||
|
||||
def sponsorship_color_hex
|
||||
hexes = { "gold" => "linear-gradient(to right, #faf0e6 8%, #faf3e6 18%, #fcf6eb 33%);",
|
||||
"silver" => "linear-gradient(to right, #e3e3e3 8%, #f0eded 18%, #e8e8e8 33%);",
|
||||
"bronze" => "linear-gradient(to right, #ebe2d3 8%, #f5eee1 18%, #ede6d8 33%);" }
|
||||
hexes[sponsorship_level]
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ module ApplicationHelper
|
|||
html_variants
|
||||
classified_listings
|
||||
credits
|
||||
partnerships
|
||||
].include?(controller_name)
|
||||
end
|
||||
|
||||
|
|
@ -193,4 +194,20 @@ module ApplicationHelper
|
|||
def community_qualified_name
|
||||
"The #{ApplicationConfig['COMMUNITY_NAME']} Community"
|
||||
end
|
||||
|
||||
def sponsorship_credits_price(level)
|
||||
if level == "bronze"
|
||||
50
|
||||
elsif level == "silver"
|
||||
300
|
||||
elsif level == "gold"
|
||||
4000
|
||||
elsif level == "tag"
|
||||
500
|
||||
elsif level == "media"
|
||||
25
|
||||
elsif level == "editorial"
|
||||
500
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ class Organization < ApplicationRecord
|
|||
validates :jobs_email, email: true, allow_blank: true
|
||||
validates :text_color_hex, format: /\A#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})\z/, allow_blank: true
|
||||
validates :bg_color_hex, format: /\A#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})\z/, allow_blank: true
|
||||
validates :sponsorship_level, inclusion: { in: %w[gold silver bronze] }, allow_nil: true
|
||||
validates :slug,
|
||||
presence: true,
|
||||
uniqueness: { case_sensitive: false },
|
||||
|
|
@ -40,6 +41,7 @@ class Organization < ApplicationRecord
|
|||
message: "Integer only. No sign allowed.",
|
||||
allow_blank: true }
|
||||
validates :tech_stack, :story, length: { maximum: 640 }
|
||||
validates :sponsorship_status, inclusion: { in: %w[none pending live] }
|
||||
validates :cta_button_url,
|
||||
url: { allow_blank: true, no_local: true, schemes: %w[https http] }
|
||||
validates :cta_button_text, length: { maximum: 20 }
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ class Tag < ActsAsTaggableOn::Tag
|
|||
attr_accessor :tag_moderator_id, :remove_moderator_id
|
||||
|
||||
belongs_to :badge, optional: true
|
||||
belongs_to :sponsor_organization, class_name: "Organization", optional: true
|
||||
|
||||
mount_uploader :profile_image, ProfileImageUploader
|
||||
mount_uploader :social_image, ProfileImageUploader
|
||||
|
|
@ -27,6 +28,7 @@ class Tag < ActsAsTaggableOn::Tag
|
|||
validates :bg_color_hex,
|
||||
format: /\A#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})\z/, allow_nil: true
|
||||
validates :category, inclusion: { in: ALLOWED_CATEGORIES }
|
||||
validates :sponsorship_status, inclusion: { in: %w[none pending live] }
|
||||
|
||||
validate :validate_alias
|
||||
before_validation :evaluate_markdown
|
||||
|
|
|
|||
|
|
@ -17,6 +17,12 @@ class OrganizationPolicy < ApplicationPolicy
|
|||
OrganizationMembership.exists?(user_id: user.id, organization_id: record.id)
|
||||
end
|
||||
|
||||
def admin_of_org?
|
||||
return false if record.blank?
|
||||
|
||||
OrganizationMembership.exists?(user_id: user.id, organization_id: record.id, type_of_user: "admin")
|
||||
end
|
||||
|
||||
def generate_new_secret?
|
||||
update?
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,22 +10,11 @@
|
|||
<img src="<%= asset_path "emoji/emoji-one-heart.png" %>" alt="emoji heart" />
|
||||
</span>
|
||||
</header>
|
||||
<% @sponsors = Organization.where(is_gold_sponsor: true).order("sponsorship_featured_number ASC") %>
|
||||
<% @sponsors = Organization.where(sponsorship_level: "gold", sponsorship_status: "live").order("sponsorship_featured_number ASC") %>
|
||||
<% if @sponsors.any? %>
|
||||
<div class="widget-body">
|
||||
<% @sponsors.each do |organization| %>
|
||||
<div class="sidebar-sponsor">
|
||||
<a class="partner-link" href="<%= organization.sponsorship_url %>" target="_blank" data-details="<%= organization.slug %>__image">
|
||||
<img src="<%= cloudinary(organization.nav_image_url) %>" style="margin-bottom:8px;" alt="<%= organization.name %> logo" loading="lazy" class="partner-image-light-mode" />
|
||||
<img src="<%= cloudinary(organization.dark_nav_image_url || organization.nav_image_url) %>" style="margin-bottom:8px;" alt="<%= organization.name %> logo" loading="lazy" class="partner-image-dark-mode" />
|
||||
</a>
|
||||
<div class="sponsor-tagline" style="display:inline;">
|
||||
<%= organization.sponsorship_tagline %>
|
||||
<a class="partner-link sponsor-learn-more" href="<%= organization.sponsorship_url %>" target="_blank" data-details="<%= organization.slug %>__learn-more">
|
||||
Learn More
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<%= render "articles/single_sponsor", organization: organization %>
|
||||
<% end %>
|
||||
<div class="sponsors-love-message">
|
||||
We are grateful for wonderful sponsors who help sustain the <%= ApplicationConfig["COMMUNITY_NAME"] %> community.
|
||||
|
|
|
|||
12
app/views/articles/_single_sponsor.html.erb
Normal file
12
app/views/articles/_single_sponsor.html.erb
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<div class="sidebar-sponsor">
|
||||
<a class="partner-link" href="<%= organization.sponsorship_url %>" target="_blank" data-details="<%= organization.slug %>__image">
|
||||
<img src="<%= cloudinary(organization.nav_image_url) %>" style="margin-bottom:8px;" alt="<%= organization.name %> logo" loading="lazy" class="partner-image-light-mode" />
|
||||
<img src="<%= cloudinary(organization.dark_nav_image_url || organization.nav_image_url) %>" style="margin-bottom:8px;" alt="<%= organization.name %> logo" loading="lazy" class="partner-image-dark-mode" />
|
||||
</a>
|
||||
<div class="sponsor-tagline" style="display:inline;">
|
||||
<%= organization.sponsorship_tagline %>
|
||||
<a class="partner-link sponsor-learn-more" href="<%= organization.sponsorship_url %>" target="_blank" data-details="<%= organization.slug %>__learn-more">
|
||||
Learn More
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -35,6 +35,16 @@
|
|||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if @tag_model.sponsor_organization_id && @tag_model.sponsorship_status == "live" %>
|
||||
<div class="widget">
|
||||
<header>
|
||||
<h4><%= @tag %> is sponsored by</h4>
|
||||
</header>
|
||||
<div class="widget-body">
|
||||
<%= render "articles/single_sponsor", organization: @tag_model.sponsor_organization %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if @moderators.present? %>
|
||||
<div class="widget">
|
||||
<header>
|
||||
|
|
|
|||
|
|
@ -22,7 +22,14 @@
|
|||
<% end %>
|
||||
<% if @credits.size > 0 %>
|
||||
<center>
|
||||
<a href="/listings/new">Create a Listing</a>
|
||||
<p>
|
||||
<a href="/listings/new">Create a Listing</a>
|
||||
</p>
|
||||
<% if @organizations.present? %>
|
||||
<p>
|
||||
<a href="/partnerships">View Partnership Opportunities</a>
|
||||
</p>
|
||||
<% end %>
|
||||
</center>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
<div id="sidebar-wrapper-right" class="sidebar-wrapper sidebar-wrapper-right">
|
||||
<div class="sidebar-bg" id="sidebar-bg-right"></div>
|
||||
<div class="side-bar sidebar-additional showing" id="sidebar-additional">
|
||||
<% if @organization.sponsorship_status == "live" %>
|
||||
<div class="sidebar-sponsorship-level" style="background:<%= @organization.decorate.sponsorship_color_hex %>">
|
||||
<%= @organization.sponsorship_level.capitalize %> Community Sponsor ❤️
|
||||
</div>
|
||||
<% end %>
|
||||
<% if @organization.users.present? %>
|
||||
<div class="widget">
|
||||
<div class="widget-suggested-follows-container">
|
||||
|
|
|
|||
|
|
@ -15,6 +15,10 @@
|
|||
display: inline;
|
||||
left: 0;
|
||||
}
|
||||
.sponsor-level-headline {
|
||||
padding:5px 18px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="container article">
|
||||
|
|
@ -28,13 +32,12 @@
|
|||
|
||||
<h4>
|
||||
<img src="<%= cloudinary("https://thepracticaldev.s3.amazonaws.com/i/2zmukvll98je8qsdyewq.png", 30) %>" alt="golden badge">
|
||||
<span style="background-color: #fefa87; padding:3px;">Gold Sponsors</span>
|
||||
<span class="sponsor-level-headline" style="background-color: #fefa87;">Gold Sponsors</span>
|
||||
<img src="<%= cloudinary("https://thepracticaldev.s3.amazonaws.com/i/2zmukvll98je8qsdyewq.png", 30) %>" alt="golden badge">
|
||||
</h4>
|
||||
<div id="gold-sponsors">
|
||||
<% Organization.where(is_gold_sponsor: true).order("sponsorship_featured_number ASC").each do |organization| %>
|
||||
<% Organization.where(sponsorship_level: "gold").order("sponsorship_featured_number ASC").each do |organization| %>
|
||||
<a href="<%= organization.sponsorship_url %>"><img src="<%= cloudinary(organization.nav_image_url, 250) %>"></a>
|
||||
|
||||
<p>
|
||||
<%= organization.sponsorship_blurb_html.html_safe %>
|
||||
</p>
|
||||
|
|
@ -42,6 +45,37 @@
|
|||
<hr />
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<h4>
|
||||
<img src="<%= cloudinary("https://thepracticaldev.s3.amazonaws.com/i/2zmukvll98je8qsdyewq.png", 30) %>" alt="silver badge">
|
||||
<span class="sponsor-level-headline" style="background-color: #d8e1f0;">Silver Sponsors</span>
|
||||
<img src="<%= cloudinary("https://thepracticaldev.s3.amazonaws.com/i/2zmukvll98je8qsdyewq.png", 30) %>" alt="silver badge">
|
||||
</h4>
|
||||
<div id="silver-sponsors">
|
||||
<% Organization.where(sponsorship_level: "silver").order("sponsorship_featured_number ASC").each do |organization| %>
|
||||
<a href="<%= organization.sponsorship_url %>"><img src="<%= cloudinary(organization.nav_image_url, 250) %>"></a>
|
||||
<p>
|
||||
<%= organization.sponsorship_blurb_html.html_safe %>
|
||||
</p>
|
||||
<hr />
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<h4>
|
||||
<img src="<%= cloudinary("https://thepracticaldev.s3.amazonaws.com/i/2zmukvll98je8qsdyewq.png", 30) %>" alt="bronze badge">
|
||||
<span class="sponsor-level-headline" style="background-color: #fcd6bb;">Bronze Sponsors</span>
|
||||
<img src="<%= cloudinary("https://thepracticaldev.s3.amazonaws.com/i/2zmukvll98je8qsdyewq.png", 30) %>" alt="bronze badge">
|
||||
</h4>
|
||||
<div id="bronze-sponsors">
|
||||
<% Organization.where(sponsorship_level: "bronze").order("sponsorship_featured_number ASC").each do |organization| %>
|
||||
<a href="<%= organization.sponsorship_url %>"><img src="<%= cloudinary(organization.nav_image_url, 250) %>"></a>
|
||||
<p>
|
||||
<%= organization.sponsorship_blurb_html.html_safe %>
|
||||
</p>
|
||||
<hr />
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<h5> Interested in sponsoring dev.to? Email <a href="mailto:peter@dev.to">peter@dev.to</a></h5>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
5
app/views/partnerships/_bronze_sponsor_copy.html.erb
Normal file
5
app/views/partnerships/_bronze_sponsor_copy.html.erb
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<h1>Bronze Sponsorship</h1>
|
||||
<h3>🚀 Info</h3>
|
||||
<p>
|
||||
TBD
|
||||
</p>
|
||||
5
app/views/partnerships/_editorial_consult_copy.html.erb
Normal file
5
app/views/partnerships/_editorial_consult_copy.html.erb
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<h1>Editorial Consultation</h1>
|
||||
<h3>🚀 Info</h3>
|
||||
<p>
|
||||
TBD
|
||||
</p>
|
||||
122
app/views/partnerships/_form.html.erb
Normal file
122
app/views/partnerships/_form.html.erb
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
<% org = current_user.admin_organizations.first %>
|
||||
|
||||
<% if org == nil %>
|
||||
<div class="partner-credits-explainer">
|
||||
<h4>What next?</h4>
|
||||
<h3>Create an Organization</h3>
|
||||
<p>
|
||||
<em>Organizations act as a publication and a way for your team to interact with DEV on behalf of the company</em>
|
||||
</p>
|
||||
<p>
|
||||
Come back to this page once you have created an organization. Only organization <em>admins</em> may purchase sponsorships.
|
||||
</p>
|
||||
<a href="/settings/organization">Create Organization</a>
|
||||
</div>
|
||||
<% else %>
|
||||
<% current_user.admin_organizations.each do |org| %>
|
||||
<% if org.credits.where(spent: false).size < sponsorship_credits_price(level) %>
|
||||
<div class="partner-credits-explainer">
|
||||
<h4>What next?</h4>
|
||||
<h3><img src="<%= ProfileImage.new(org).get(90) %>" /> Purchase Credits for @<%= org.slug %></h3>
|
||||
<% if org.credits.where(spent: false).size > 0 %>
|
||||
<div style="font-size: 0.88em;"><em>This organization account has <%= org.credits.where(spent: false).size %> credits available </em></div>
|
||||
<% end %>
|
||||
<p>
|
||||
<em>Credits are your wallet for flexibly managing all your DEV partnerships.</em>
|
||||
</p>
|
||||
<p>
|
||||
Credits can be purchased via company credit card, and once in your account you can use them for different promotions.
|
||||
</p>
|
||||
<p>
|
||||
Credits can be purchased in bulk for discounts on all future sponsorships and partnerships, or in small batches to test the waters.
|
||||
</p>
|
||||
<a href="/credits/purchase?organization_id=<%= org.id %>" data-no-instant>Get Credits</a>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="partner-credits-explainer">
|
||||
<% if %w[gold silver bronze].include?(level) %>
|
||||
<h3><img src="<%= ProfileImage.new(org).get(90) %>" />@<%= org.slug %></h3>
|
||||
<div style="font-size: 0.88em;"><em>This organization account has <%= org.credits.where(spent: false).size %> credits available </em></div>
|
||||
<% if org.sponsorship_level == level %>
|
||||
<div class="partner-explainer-notice">
|
||||
🎉 You are Subscribed as a <%= level.capitalize %> Sponsor.
|
||||
<% if org.sponsorship_status == "pending" %>
|
||||
<br /><br />Your placement is <em>pending</em>.
|
||||
<% end %>
|
||||
</div>
|
||||
<% elsif org.sponsorship_level.present? %>
|
||||
<div class="partner-explainer-notice">
|
||||
🛑 You are already subscribed as a <%= org.sponsorship_level %> sponsor. Contact partnerships@dev.to to change plans.
|
||||
</div>
|
||||
<% else %>
|
||||
<h2><%= level.capitalize %> Sponsor Subscription</h2>
|
||||
<%= form_tag "/partnerships" do %>
|
||||
<%= hidden_field_tag(:organization_id, org.id) %>
|
||||
<%= hidden_field_tag(:sponsorship_level, level) %>
|
||||
<h4>Sponsorship message/brand instructions:</h4>
|
||||
<%= text_area_tag(:sponsorship_instructions, nil, placeholder: "Include brand guideline links and detailed instructions about the message you are trying to get across. DEV editors will use these guidelines contextually depending on sponsorship.") %>
|
||||
<button>Subscribe for <%= sponsorship_credits_price(level) %> credits</button>
|
||||
<p style="font-size: 0.88em;">
|
||||
<em>
|
||||
This subscription will renew every month with credits in your account. If there are no credits, 50 credits will be purchased at the appropriate price. You can cancel this automatic sponsorship subscription at any time.
|
||||
</em>
|
||||
</p>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% elsif level == "tag" %>
|
||||
<h3><img src="<%= ProfileImage.new(org).get(90) %>" />@<%= org.slug %></h3>
|
||||
<div style="font-size: 0.88em;"><em>This organization account has <%= org.credits.where(spent: false).size %> credits available </em></div>
|
||||
<br />
|
||||
<%= form_tag "/partnerships" do %>
|
||||
<%= hidden_field_tag(:organization_id, org.id) %>
|
||||
<%= hidden_field_tag(:sponsorship_level, level) %>
|
||||
<% Tag.where(sponsor_organization_id: org.id).each do |tag| %>
|
||||
<div class="partner-explainer-notice">
|
||||
🎉 You are Subscribed as the sponsor of #<%= tag.name %>.
|
||||
</div>
|
||||
<% end %>
|
||||
<%= select_tag "tag_name", options_for_select(Tag.where(sponsor_organization_id: nil, supported: true).pluck(:name)) %>
|
||||
<button>Sponsor Tag</button>
|
||||
<p style="font-size: 0.88em;">
|
||||
<em>
|
||||
This subscription will renew every month with credits in your account. If there are no credits, 50 credits will be purchased at the appropriate price. You can cancel this automatic sponsorship subscription at any time.
|
||||
</em>
|
||||
</p>
|
||||
<% end %>
|
||||
<% elsif level == "media" %>
|
||||
<h3><img src="<%= ProfileImage.new(org).get(90) %>" />@<%= org.slug %></h3>
|
||||
<div style="font-size: 0.88em;"><em>This organization account has <%= org.credits.where(spent: false).size %> credits available </em></div>
|
||||
<br />
|
||||
<%= form_tag "/partnerships" do %>
|
||||
<%= hidden_field_tag(:organization_id, org.id) %>
|
||||
<%= hidden_field_tag(:sponsorship_level, level) %>
|
||||
<%= number_field_tag(:sponsorship_amount, nil, placeholder: "Number of credits") %>
|
||||
<button>Add spend to your media sponsorship</button>
|
||||
<p style="font-size: 0.88em;">
|
||||
<em>
|
||||
Credits will be allotted flexibly use in DEV-produced podcasts, videos and other media content. You will be notified as it is being distributed.
|
||||
</em>
|
||||
</p>
|
||||
<% end %>
|
||||
<% elsif level == "editorial" %>
|
||||
<h3><img src="<%= ProfileImage.new(org).get(90) %>" />@<%= org.slug %></h3>
|
||||
<div style="font-size: 0.88em;"><em>This organization account has <%= org.credits.where(spent: false).size %> credits available </em></div>
|
||||
<br />
|
||||
<%= form_tag "/partnerships" do %>
|
||||
<%= hidden_field_tag(:organization_id, org.id) %>
|
||||
<%= hidden_field_tag(:sponsorship_level, level) %>
|
||||
<button>Sign Up for Editorial Consulting</button>
|
||||
<p style="font-size: 1.1em;">
|
||||
You will be contacted by the DEV team within one day of signing up for this service.
|
||||
</p>
|
||||
<p style="font-size: 0.88em;">
|
||||
<em>
|
||||
This subscription will renew every month with credits in your account. If there are no credits, 50 credits will be purchased at the appropriate price. You can cancel this automatic sponsorship subscription at any time.
|
||||
</em>
|
||||
</p>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
5
app/views/partnerships/_gold_sponsor_copy.html.erb
Normal file
5
app/views/partnerships/_gold_sponsor_copy.html.erb
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<h1>Gold Sponsorship</h1>
|
||||
<h3>🚀 Info</h3>
|
||||
<p>
|
||||
TBD
|
||||
</p>
|
||||
5
app/views/partnerships/_media_sponsor_copy.html.erb
Normal file
5
app/views/partnerships/_media_sponsor_copy.html.erb
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<h1>Media Sponsorship</h1>
|
||||
<h3>🚀 Info</h3>
|
||||
<p>
|
||||
TBD
|
||||
</p>
|
||||
5
app/views/partnerships/_silver_sponsor_copy.html.erb
Normal file
5
app/views/partnerships/_silver_sponsor_copy.html.erb
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<h1>Silver Sponsorship</h1>
|
||||
<h3>🚀 Info</h3>
|
||||
<p>
|
||||
TBD
|
||||
</p>
|
||||
5
app/views/partnerships/_tag_sponsor_copy.html.erb
Normal file
5
app/views/partnerships/_tag_sponsor_copy.html.erb
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<h1>Tag Sponsorship</h1>
|
||||
<h3>🚀 Info</h3>
|
||||
<p>
|
||||
TBD
|
||||
</p>
|
||||
122
app/views/partnerships/index.html.erb
Normal file
122
app/views/partnerships/index.html.erb
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
<% title "Sponsors" %>
|
||||
|
||||
<style>
|
||||
<% cache "partnership-org-section-credits-#{ApplicationConfig['DEPLOYMENT_SIGNATURE']}", expires_in: 10.hours do %>
|
||||
<%= Rails.application.assets["partnerships.css"].to_s.html_safe %>
|
||||
<% end %>
|
||||
</style>
|
||||
|
||||
<div class="partnerships-container">
|
||||
<h1>Partner With <img src="<%= asset_path "rainbowdev.svg" %>" /> </h1>
|
||||
<h3>🚀 Reach</h3>
|
||||
<p>
|
||||
DEV reaches over 3.5 million unique visitors per month with highly technical content. That includes signed up members (<%= number_with_delimiter User.count %>) and yet-to-sign-up visitors from the open web.
|
||||
</p>
|
||||
<h3>❤️ Community</h3>
|
||||
<p>
|
||||
DEV is truly a leading community for software development and is leading the way to a more inclusive industry where everyone is welcome.
|
||||
</p>
|
||||
<h3>💎 Quality</h3>
|
||||
<p>
|
||||
DEV does not overwhelm members with popup messages, irrelevent ads or anything else that sours the user experience. We treat each visitor with care.
|
||||
<h3>🤓 Expertise</h3>
|
||||
<p>
|
||||
DEV has experts on staff to help you craft your message to the community centered around and create positive mutual outcomes.
|
||||
</p>
|
||||
|
||||
<div class="partnership-options">
|
||||
<div class="partnership-option-card">
|
||||
<h2>Bronze Sponsorship</h2>
|
||||
<ul>
|
||||
<li>
|
||||
👀 Recognition on sponsors page (logo only)
|
||||
</li>
|
||||
<li>
|
||||
🙌 Placement in monthly sponsor-awareness thread (name only)
|
||||
</li>
|
||||
<li>
|
||||
🎉 Placement in home-page "sponsor awareness box" (rotation)
|
||||
</li>
|
||||
</ul>
|
||||
<a class="partnership-option-cta" href="/partnerships/bronze-sponsor">Full Details</a>
|
||||
</div>
|
||||
<div class="partnership-option-card">
|
||||
<h2>Silver Sponsorship</h2>
|
||||
<ul>
|
||||
<li>
|
||||
👀 Recognition on sponsors page (logo + short blurb)
|
||||
</li>
|
||||
<li>
|
||||
🙌 Placement in monthly sponsor-awareness thread (logo + short blurb)
|
||||
</li>
|
||||
<li>
|
||||
🎉 Placement in home-page "sponsor awareness box" (rotation)
|
||||
</li>
|
||||
</ul>
|
||||
<a class="partnership-option-cta" href="/partnerships/silver-sponsor">Full Details</a>
|
||||
</div>
|
||||
<div class="partnership-option-card">
|
||||
<h2>Gold Sponsorship</h2>
|
||||
<ul>
|
||||
<li>
|
||||
👀 Recognition on sponsors page (logo + full writeup)
|
||||
</li>
|
||||
<li>
|
||||
🙌 Full-time home page brand placement + tagline + link
|
||||
</li>
|
||||
<li>
|
||||
🎉 Shoutout + article placement in weekly newsletter
|
||||
</li>
|
||||
</ul>
|
||||
<a class="partnership-option-cta" href="/partnerships/gold-sponsor">Full Details</a>
|
||||
</div>
|
||||
<div class="partnership-option-card">
|
||||
<h2>Tag Sponsorship</h2>
|
||||
<ul>
|
||||
<li>
|
||||
👀 Full Writeup on tag sidebar
|
||||
</li>
|
||||
<li>
|
||||
🙌 Recognition in tags overview page
|
||||
</li>
|
||||
<li>
|
||||
🎉 Recognition on organization profile
|
||||
</li>
|
||||
</ul>
|
||||
<a class="partnership-option-cta" href="/partnerships/tag-sponsor">Full Details</a>
|
||||
</div>
|
||||
<div class="partnership-option-card">
|
||||
<h2>Media Sponsorship</h2>
|
||||
<ul>
|
||||
<li>
|
||||
👀 Sponsor custom productions such as video and podcasts
|
||||
</li>
|
||||
<li>
|
||||
🙌 Pre-purchase for agile placement in new things
|
||||
</li>
|
||||
<li>
|
||||
🎉 Creative copy written by DEV team
|
||||
</li>
|
||||
</ul>
|
||||
<a class="partnership-option-cta" href="/partnerships/media-sponsor">Full Details</a>
|
||||
</div>
|
||||
<div class="partnership-option-card">
|
||||
<h2>Editorial Consultation</h2>
|
||||
<ul>
|
||||
<li>
|
||||
👀 Weekly editorial notes and suggestions to help your devrels make the most of DEV
|
||||
</li>
|
||||
<li>
|
||||
🙌 First notice of new on-site opportunities and events
|
||||
</li>
|
||||
<li>
|
||||
🎉 Premium support
|
||||
</li>
|
||||
</ul>
|
||||
<a class="partnership-option-cta" href="/partnerships/editorial-consult">Full Details</a>
|
||||
</div>
|
||||
</div>
|
||||
<div style="text-align: center;">
|
||||
<h2>Questions about anything?<br /><br />Email <a href="mailto:partners@dev.to">partners@dev.to</a></h1>
|
||||
</div>
|
||||
</div>
|
||||
31
app/views/partnerships/show.html.erb
Normal file
31
app/views/partnerships/show.html.erb
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<% title "#{params[:option].titleize} Overview" %>
|
||||
|
||||
<style>
|
||||
<% cache "partnership-org-section-credits-#{ApplicationConfig['DEPLOYMENT_SIGNATURE']}", expires_in: 10.hours do %>
|
||||
<%= Rails.application.assets["partnerships.css"].to_s.html_safe %>
|
||||
<% end %>
|
||||
</style>
|
||||
|
||||
<div class="partnerships-container partnerships-container-show">
|
||||
<p><a href="/partnerships">👈 back to partnerships list</a></p>
|
||||
<% if params[:option] == "gold-sponsor" %>
|
||||
<%= render "gold_sponsor_copy" %>
|
||||
<% elsif params[:option] == "silver-sponsor" %>
|
||||
<%= render "silver_sponsor_copy" %>
|
||||
<% elsif params[:option] == "bronze-sponsor" %>
|
||||
<%= render "bronze_sponsor_copy" %>
|
||||
<% elsif params[:option] == "tag-sponsor" %>
|
||||
<%= render "tag_sponsor_copy" %>
|
||||
<% elsif params[:option] == "media-sponsor" %>
|
||||
<%= render "media_sponsor_copy" %>
|
||||
<% elsif params[:option] == "editorial-consult" %>
|
||||
<%= render "editorial_consult_copy" %>
|
||||
<% end %>
|
||||
<% if user_signed_in? %>
|
||||
<%= render "form", level: params[:option].split("-")[0] %>
|
||||
<% else %>
|
||||
<div class="partner-credits-explainer">
|
||||
<a href="/enter">Sign in to get started</a>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
@ -150,6 +150,7 @@ Rails.application.routes.draw do
|
|||
resources :poll_votes, only: %i[show create]
|
||||
resources :poll_skips, only: [:create]
|
||||
resources :profile_pins, only: %i[create update]
|
||||
resources :partnerships, only: %i[index create]
|
||||
|
||||
get "/chat_channel_memberships/find_by_chat_channel_id" => "chat_channel_memberships#find_by_chat_channel_id"
|
||||
get "/credits/purchase" => "credits#new"
|
||||
|
|
@ -171,6 +172,8 @@ Rails.application.routes.draw do
|
|||
post "/chat_channels/create_chat" => "chat_channels#create_chat"
|
||||
post "/chat_channels/block_chat" => "chat_channels#block_chat"
|
||||
get "/live/:username" => "twitch_live_streams#show"
|
||||
get "/partnerships/:option" => "partnerships#show"
|
||||
|
||||
|
||||
post "/pusher/auth" => "pusher#auth"
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
class AddAdditionalSponsorOptionsToOrganizations < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :organizations, :sponsorship_level, :string
|
||||
add_column :organizations, :sponsorship_expires_at, :datetime
|
||||
add_column :organizations, :sponsorship_status, :string, default: "none"
|
||||
add_column :organizations, :sponsorship_instructions, :text, default: ""
|
||||
add_column :organizations, :sponsorship_instructions_updated_at, :datetime
|
||||
add_column :tags, :sponsor_organization_id, :integer
|
||||
add_column :tags, :sponsorship_status, :string, default: "none"
|
||||
end
|
||||
end
|
||||
|
|
@ -586,7 +586,12 @@ ActiveRecord::Schema.define(version: 2019_07_03_003817) do
|
|||
t.string "slug"
|
||||
t.integer "spent_credits_count", default: 0, null: false
|
||||
t.text "sponsorship_blurb_html"
|
||||
t.datetime "sponsorship_expires_at"
|
||||
t.integer "sponsorship_featured_number", default: 0
|
||||
t.text "sponsorship_instructions", default: ""
|
||||
t.datetime "sponsorship_instructions_updated_at"
|
||||
t.string "sponsorship_level"
|
||||
t.string "sponsorship_status", default: "none"
|
||||
t.string "sponsorship_tagline"
|
||||
t.string "sponsorship_url"
|
||||
t.string "state"
|
||||
|
|
@ -858,6 +863,8 @@ ActiveRecord::Schema.define(version: 2019_07_03_003817) do
|
|||
t.text "rules_markdown"
|
||||
t.string "short_summary"
|
||||
t.string "social_image"
|
||||
t.integer "sponsor_organization_id"
|
||||
t.string "sponsorship_status", default: "none"
|
||||
t.string "submission_rules_headsup"
|
||||
t.text "submission_template"
|
||||
t.boolean "supported", default: false
|
||||
|
|
|
|||
158
spec/requests/partnerships_spec.rb
Normal file
158
spec/requests/partnerships_spec.rb
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
require "rails_helper"
|
||||
|
||||
RSpec.describe "Pages", type: :request do
|
||||
describe "GET /partnerships" do
|
||||
context "when user is logged in" do
|
||||
before do
|
||||
get "/partnerships"
|
||||
end
|
||||
|
||||
it "renders main text" do
|
||||
expect(response.body).to include "Partner With"
|
||||
end
|
||||
end
|
||||
|
||||
context "when user is not logged in" do
|
||||
before do
|
||||
user = create(:user)
|
||||
sign_in user
|
||||
get "/partnerships"
|
||||
end
|
||||
|
||||
it "renders main text" do
|
||||
expect(response.body).to include "Partner With"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /partnerships/:show" do
|
||||
let(:user) { create(:user) }
|
||||
|
||||
context "when user is logged in" do
|
||||
before do
|
||||
sign_in user
|
||||
end
|
||||
|
||||
describe "shared basic functionality" do
|
||||
it "gets bronze sponsorship page" do
|
||||
get "/partnerships/bronze-sponsor"
|
||||
expect(response.body).to include("Bronze Sponsorship")
|
||||
end
|
||||
it "asks user to create org if not created" do
|
||||
get "/partnerships/bronze-sponsor"
|
||||
expect(response.body).to include("Create an Organization")
|
||||
end
|
||||
it "asks user to purchase credits if not purchased" do
|
||||
organization = create(:organization)
|
||||
OrganizationMembership.create(user_id: user.id, organization_id: organization.id, type_of_user: "admin")
|
||||
get "/partnerships/bronze-sponsor"
|
||||
expect(response.body).to include("Purchase Credits")
|
||||
end
|
||||
it "includes sponsorship form if organization has credits" do
|
||||
organization = create(:organization)
|
||||
OrganizationMembership.create(user_id: user.id, organization_id: organization.id, type_of_user: "admin")
|
||||
Credit.add_to_org(organization, 100)
|
||||
get "/partnerships/bronze-sponsor"
|
||||
expect(response.body).to include("This subscription will renew every month")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when user is not logged in" do
|
||||
describe "shared basic functionality" do
|
||||
it "gets bronze sponsorship page" do
|
||||
get "/partnerships/bronze-sponsor"
|
||||
expect(response.body).to include("Bronze Sponsorship")
|
||||
expect(response.body).to include("Sign in to get started")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST /partnerships" do
|
||||
let(:user) { create(:user) }
|
||||
let(:organization) { create(:organization) }
|
||||
|
||||
context "when user is logged in as an admin and has enough credits" do
|
||||
before do
|
||||
OrganizationMembership.create(user_id: user.id, organization_id: organization.id, type_of_user: "admin")
|
||||
Credit.add_to_org(organization, 2000)
|
||||
sign_in user
|
||||
end
|
||||
|
||||
it "subscribes to bronze sponsorship" do
|
||||
post "/partnerships", params: {
|
||||
sponsorship_level: "bronze",
|
||||
organization_id: organization.id
|
||||
}
|
||||
expect(organization.reload.sponsorship_level).to eq("bronze")
|
||||
end
|
||||
it "subscribes to silver sponsorship" do
|
||||
post "/partnerships", params: {
|
||||
sponsorship_level: "silver",
|
||||
organization_id: organization.id
|
||||
}
|
||||
expect(organization.reload.sponsorship_level).to eq("silver")
|
||||
end
|
||||
xit "subscribes to gold sponsorship" do # skipped for now do to high credit need (not sure making this self serve makes sense)
|
||||
post "/partnerships", params: {
|
||||
sponsorship_level: "gold",
|
||||
organization_id: organization.id
|
||||
}
|
||||
expect(organization.reload.sponsorship_level).to eq("gold")
|
||||
end
|
||||
it "subscribes to editorial subscription" do
|
||||
post "/partnerships", params: {
|
||||
sponsorship_level: "editorial",
|
||||
organization_id: organization.id
|
||||
}
|
||||
expect(organization.reload.credits.where(spent: false).size).to eq(1500)
|
||||
end
|
||||
it "subscribes to media sponsorship" do
|
||||
post "/partnerships", params: {
|
||||
sponsorship_level: "media",
|
||||
organization_id: organization.id,
|
||||
sponsorship_amount: 900
|
||||
}
|
||||
expect(organization.reload.credits.where(spent: false).size).to eq(1100)
|
||||
end
|
||||
it "subscribes to tag sponsorship" do
|
||||
tag = create(:tag)
|
||||
post "/partnerships", params: {
|
||||
sponsorship_level: "tag",
|
||||
organization_id: organization.id,
|
||||
sponsorship_amount: 900,
|
||||
tag_name: tag.name
|
||||
}
|
||||
expect(organization.reload.credits.where(spent: false).size).to eq(1500)
|
||||
expect(tag.reload.sponsor_organization_id).to eq(organization.id)
|
||||
end
|
||||
it "updates sponsorship instructions if new instructions" do
|
||||
post "/partnerships", params: {
|
||||
sponsorship_level: "bronze",
|
||||
organization_id: organization.id,
|
||||
sponsorship_instructions: "hello there"
|
||||
}
|
||||
expect(organization.reload.sponsorship_instructions).to include("hello there")
|
||||
expect(organization.reload.sponsorship_instructions_updated_at).to be > 30.seconds.ago
|
||||
end
|
||||
end
|
||||
|
||||
context "when user is logged in as a non-admin" do
|
||||
before do
|
||||
OrganizationMembership.create(user_id: user.id, organization_id: organization.id, type_of_user: "member")
|
||||
Credit.add_to_org(organization, 2000)
|
||||
sign_in user
|
||||
end
|
||||
|
||||
it "subscribes to bronze sponsorship" do
|
||||
expect do
|
||||
post "/partnerships", params: {
|
||||
sponsorship_level: "bronze",
|
||||
organization_id: organization.id
|
||||
}
|
||||
end.to raise_error(Pundit::NotAuthorizedError)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -42,13 +42,13 @@ RSpec.describe "StoriesIndex", type: :request do
|
|||
end
|
||||
|
||||
it "has sponsors displayed" do
|
||||
org = create(:organization, is_gold_sponsor: true, sponsorship_tagline: "Oh Yeah!!!")
|
||||
org = create(:organization, sponsorship_level: "gold", sponsorship_tagline: "Oh Yeah!!!", sponsorship_status: "live")
|
||||
get "/"
|
||||
expect(response.body).to include(org.sponsorship_tagline)
|
||||
end
|
||||
|
||||
it "does not display non-sponsor org" do
|
||||
org = create(:organization, is_gold_sponsor: false, sponsorship_tagline: "Oh Yeah!!!")
|
||||
org = create(:organization, sponsorship_level: nil, sponsorship_tagline: "Oh Yeah!!!")
|
||||
get "/"
|
||||
expect(response.body).not_to include(org.sponsorship_tagline)
|
||||
end
|
||||
|
|
@ -101,5 +101,21 @@ RSpec.describe "StoriesIndex", type: :request do
|
|||
get "/t/#{tag2.name}"
|
||||
expect(response.body).to redirect_to "/t/#{tag.name}"
|
||||
end
|
||||
|
||||
it "does not render sponsor if not live" do
|
||||
organization = create(:organization, sponsorship_tagline: "Oh Yeah!!!")
|
||||
tag = create(:tag, sponsor_organization_id: organization.id)
|
||||
get "/t/#{tag.name}"
|
||||
expect(response.body).not_to include("is sponsored by")
|
||||
expect(response.body).not_to include(organization.sponsorship_tagline)
|
||||
end
|
||||
|
||||
it "renders sponsor" do
|
||||
organization = create(:organization, sponsorship_tagline: "Oh Yeah!!!!!!")
|
||||
tag = create(:tag, sponsor_organization_id: organization.id, sponsorship_status: "live")
|
||||
get "/t/#{tag.name}"
|
||||
expect(response.body).to include("is sponsored by")
|
||||
expect(response.body).to include(organization.sponsorship_tagline)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -38,16 +38,28 @@ RSpec.describe "UserProfiles", type: :request do
|
|||
get "/#{old_username}"
|
||||
expect(response).to redirect_to("/#{user.username}")
|
||||
end
|
||||
context "organizationd" do
|
||||
it "renders organization page if org" do
|
||||
get organization.path
|
||||
expect(response.body).to include CGI.escapeHTML(organization.name)
|
||||
end
|
||||
|
||||
it "renders organization page if org" do
|
||||
get organization.path
|
||||
expect(response.body).to include CGI.escapeHTML(organization.name)
|
||||
end
|
||||
it "renders organization users on sidebar" do
|
||||
create(:organization_membership, user_id: user.id, organization_id: organization.id)
|
||||
get organization.path
|
||||
expect(response.body).to include user.profile_image_url
|
||||
end
|
||||
|
||||
it "renders organization users on sidebar" do
|
||||
create(:organization_membership, user_id: user.id, organization_id: organization.id)
|
||||
get organization.path
|
||||
expect(response.body).to include user.profile_image_url
|
||||
it "renders no sponsors if not sponsor" do
|
||||
get organization.path
|
||||
expect(response.body).not_to include "Gold Community Sponsor"
|
||||
end
|
||||
|
||||
it "renders sponsor if it is sponsored" do
|
||||
organization.update_columns(sponsorship_level: "gold", sponsorship_status: "live")
|
||||
get organization.reload.path
|
||||
expect(response.body).to include "Gold Community Sponsor"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue