Enable Org Pro Dashboard View (#2060)

This commit is contained in:
Andy Zhao 2019-03-18 11:58:44 -04:00 committed by Mac Siri
parent 6524817621
commit 8a3d3ae765
10 changed files with 145 additions and 60 deletions

View file

@ -21,14 +21,14 @@
margin: 0px;
}
}
.back-nav {
.rounded-btn {
font-size: calc(16px + 0.3vw);
font-family: $helvetica-condensed;
font-stretch: condensed;
padding: 4px 20px;
border-radius: 100px;
margin-right: 5px;
display: block;
display: inline-block;
width: fit-content;
margin-bottom: 10px;
color: $black;

View file

@ -31,23 +31,14 @@ class DashboardsController < ApplicationController
end
def pro
authorize current_user, :pro_user?
@current_user_article_ids = current_user.articles.pluck(:id)
@this_week_reactions = ChartDecorator.decorate(Reaction.where(reactable_id: @current_user_article_ids, reactable_type: "Article").where("created_at > ?", 1.week.ago).order("created_at ASC"))
@this_week_reactions_count = @this_week_reactions.size
@last_week_reactions_count = Reaction.where(reactable_id: @current_user_article_ids, reactable_type: "Article").where("created_at > ? AND created_at < ?", 2.weeks.ago, 1.week.ago).size
@this_month_reactions_count = Reaction.where(reactable_id: @current_user_article_ids, reactable_type: "Article").where("created_at > ?", 1.month.ago).size
@last_month_reactions_count = Reaction.where(reactable_id: @current_user_article_ids, reactable_type: "Article").where("created_at > ? AND created_at < ?", 2.months.ago, 1.months.ago).size
@this_week_comments_count = Comment.where(commentable_id: @current_user_article_ids, commentable_type: "Article").where("created_at > ?", 1.week.ago).size
@this_week_comments = ChartDecorator.decorate(Comment.where(commentable_id: @current_user_article_ids, commentable_type: "Article").where("created_at > ?", 1.week.ago))
@last_week_comments_count = @this_week_comments.size
@this_month_comments_count = Comment.where(commentable_id: @current_user_article_ids, commentable_type: "Article").where("created_at > ?", 1.month.ago).size
@last_month_comments_count = Comment.where(commentable_id: @current_user_article_ids, commentable_type: "Article").where("created_at > ? AND created_at < ?", 2.months.ago, 1.months.ago).size
@this_week_followers_count = Follow.where(followable_id: current_user.id, followable_type: "User").where("created_at > ?", 1.week.ago).size
@last_week_followers_count = Follow.where(followable_id: current_user.id, followable_type: "User").where("created_at > ? AND created_at < ?", 2.weeks.ago, 1.week.ago).size
@this_month_followers_count = Follow.where(followable_id: current_user.id, followable_type: "User").where("created_at > ?", 1.month.ago).size
@last_month_followers_count = Follow.where(followable_id: current_user.id, followable_type: "User").where("created_at > ? AND created_at < ?", 2.months.ago, 1.months.ago).size
@reactors = User.
where(id: Reaction.where(reactable_id: @current_user_article_ids, reactable_type: "Article").order("created_at DESC").limit(100).pluck(:user_id))
user_or_org = if params[:org_id]
org = Organization.find_by_id(params[:org_id])
authorize org, :pro_org_user?
org
else
authorize current_user, :pro_user?
current_user
end
@dashboard = Dashboard::Pro.new(user_or_org)
end
end

7
app/facades/dashboard.rb Normal file
View file

@ -0,0 +1,7 @@
class Dashboard
attr_reader :user_or_org
def initialize(user_or_org)
@user_or_org = user_or_org
end
end

View file

71
app/facades/pro.rb Normal file
View file

@ -0,0 +1,71 @@
class Pro < Dashboard
def initialize(user_or_org)
super
end
def user_or_org_article_ids
@user_or_org_article_ids ||=
Article.where("#{user_or_org.class.name.downcase}_id" => user_or_org.id, published: true).pluck(:id)
end
def this_week_reactions
ChartDecorator.decorate(Reaction.where(reactable_id: user_or_org_article_ids, reactable_type: "Article").where("created_at > ?", 1.week.ago).order("created_at ASC"))
end
def this_week_reactions_count
this_week_reactions.size
end
def last_week_reactions_count
Reaction.where(reactable_id: user_or_org_article_ids, reactable_type: "Article").where("created_at > ? AND created_at < ?", 2.weeks.ago, 1.week.ago).size
end
def this_month_reactions_count
Reaction.where(reactable_id: user_or_org_article_ids, reactable_type: "Article").where("created_at > ?", 1.month.ago).size
end
def last_month_reactions_count
Reaction.where(reactable_id: user_or_org_article_ids, reactable_type: "Article").where("created_at > ? AND created_at < ?", 2.months.ago, 1.months.ago).size
end
def this_week_comments
ChartDecorator.decorate(Comment.where(commentable_id: user_or_org_article_ids, commentable_type: "Article").where("created_at > ?", 1.week.ago))
end
def this_week_comments_count
this_week_comments.size
end
def last_week_comments_count
Comment.where(commentable_id: user_or_org_article_ids, commentable_type: "Article").where("created_at > ? AND created_at < ?", 2.weeks.ago, 1.week.ago).size
end
def this_month_comments_count
Comment.where(commentable_id: user_or_org_article_ids, commentable_type: "Article").where("created_at > ?", 1.month.ago).size
end
def last_month_comments_count
Comment.where(commentable_id: user_or_org_article_ids, commentable_type: "Article").where("created_at > ? AND created_at < ?", 2.months.ago, 1.months.ago).size
end
def this_week_followers_count
Follow.where(followable_id: user_or_org.id, followable_type: user_or_org.class.name).where("created_at > ?", 1.week.ago).size
end
def last_week_followers_count
Follow.where(followable_id: user_or_org.id, followable_type: user_or_org.class.name).where("created_at > ? AND created_at < ?", 2.weeks.ago, 1.week.ago).size
end
def this_month_followers_count
Follow.where(followable_id: user_or_org.id, followable_type: user_or_org.class.name).where("created_at > ?", 1.month.ago).size
end
def last_month_followers_count
Follow.where(followable_id: user_or_org.id, followable_type: user_or_org.class.name).where("created_at > ? AND created_at < ?", 2.months.ago, 1.months.ago).size
end
def reactors
User.where(id: Reaction.where(reactable_id: user_or_org_article_ids, reactable_type: "Article").
order("created_at DESC").limit(100).pluck(:user_id))
end
end

View file

@ -10,4 +10,8 @@ class OrganizationPolicy < ApplicationPolicy
def generate_new_secret?
update?
end
def pro_org_user?
user.has_role?(:pro) && user.org_admin && user.organization_id == record.id
end
end

View file

@ -1,7 +1,17 @@
<div class="dashboard-container pro-container" id="user-dashboard">
<a href="/dashboard" class="back-nav">Back to Dashboard</a>
<a href="/dashboard" class="rounded-btn">Back to Dashboard</a>
<% current_active_view = @dashboard.user_or_org.class.name %>
<% if current_active_view == "Organization" %>
<a class="rounded-btn" href="/dashboard/pro">
View Your Pro Dashboard
</a>
<% elsif current_active_view == "User" && @dashboard.user_or_org.organization_id %>
<a class="rounded-btn" href="/dashboard/pro/org/<%= @dashboard.user_or_org.organization_id %>">
View <%= @dashboard.user_or_org.organization.name %> Dashboard
</a>
<% end %>
<section class="header-card card">
<h1 class="pro-header">Pro Dashboard</h1>
<h1 class="pro-header">Pro Dashboard <%= "for #{@dashboard.user_or_org.name}" if current_active_view == "Organization" %></h1>
<p>Welcome to the pro dashboard which shows in-depth user metrics so that authors can make data-driven decisions about the developer ecosystem.</p>
<p>This dashboard will highlight deep insights especially relevant to developer relations authors and serious bloggers.</p>
</section>
@ -9,61 +19,61 @@
<div class="card">
<h4>Reactions this week</h4>
<div class="featured-stat">
<%= @this_week_reactions_count %>
<%= @dashboard.this_week_reactions_count %>
</div>
<% week_reaction_rate = @this_week_reactions_count.to_f / @last_week_reactions_count.to_f %>
<div class="stat-percentage" style="color: <%= week_reaction_rate > 1 ? "green" : "red" %>">
<%= week_reaction_rate >= 1 ? "\u25b2" : "\u25BC" %> <%= @last_week_reactions_count.positive? ? (week_reaction_rate * 100).round(2) : "infinity " %>%
<% week_reaction_rate = @dashboard.this_week_reactions_count.to_f / @dashboard.last_week_reactions_count.to_f %>
<div class="stat-percentage" style="color: <%= week_reaction_rate > 1 ? "green" : "red" %>">
<%= week_reaction_rate > 1 ? "\u25b2" : "\u25BC" %> <%= @dashboard.last_week_reactions_count.positive? ? (week_reaction_rate * 100).round(2) : "infinity " %>%
</div>
</div>
<div class="card">
<h4>Reactions this month</h4>
<div class="featured-stat">
<%= @this_month_reactions_count %>
<%= @dashboard.this_month_reactions_count %>
</div>
<% month_reaction_rate = @this_month_reactions_count.to_f / @last_month_reactions_count.to_f %>
<div class="stat-percentage" style="color: <%= month_reaction_rate > 1 ? "green" : "red" %>">
<%= month_reaction_rate >= 1 ? "\u25b2" : "\u25BC" %> <%= @last_month_reactions_count.positive? ? (month_reaction_rate * 100).round(2) : "infinity " %>%
<% month_reaction_rate = @dashboard.this_month_reactions_count.to_f / @dashboard.last_month_reactions_count.to_f %>
<div class="stat-percentage" style="color: <%= month_reaction_rate > 1 ? "green" : "red" %>">
<%= month_reaction_rate > 1 ? "\u25b2" : "\u25BC" %> <%= @dashboard.last_month_reactions_count.positive? ? (month_reaction_rate * 100).round(2) : "infinity " %>%
</div>
</div>
<div class="card">
<h4>New followers this week</h4>
<div class="featured-stat">
<%= @this_week_followers_count %>
<%= @dashboard.this_week_followers_count %>
</div>
<% week_followers_rate = @this_week_followers_count.to_f / @last_week_followers_count.to_f %>
<div class="stat-percentage" style="color: <%= week_followers_rate > 1 ? "green" : "red" %>">
<%= week_followers_rate >= 1 ? "\u25b2" : "\u25BC" %> <%= @last_week_followers_count.positive? ? (week_followers_rate * 100).round(2) : "infinity " %>%
<% week_followers_rate = @dashboard.this_week_followers_count.to_f / @dashboard.last_week_followers_count.to_f %>
<div class="stat-percentage" style="color: <%= week_followers_rate > 1 ? "green" : "red" %>">
<%= week_followers_rate > 1 ? "\u25b2" : "\u25BC" %> <%= @dashboard.last_week_followers_count.positive? ? (week_followers_rate * 100).round(2) : "infinity " %>%
</div>
</div>
<div class="card">
<h4>New followers this month</h4>
<div class="featured-stat">
<%= @this_month_followers_count %>
<%= @dashboard.this_month_followers_count %>
</div>
<% month_followers_rate = @this_month_followers_count.to_f / @last_month_followers_count.to_f %>
<div class="stat-percentage" style="color: <%= month_followers_rate > 1 ? "green" : "red" %>">
<%= month_followers_rate >= 1 ? "\u25b2" : "\u25BC" %> <%= @last_month_followers_count.positive? ? (month_followers_rate * 100).round(2) : "infinity " %>%
<% month_followers_rate = @dashboard.this_month_followers_count.to_f / @dashboard.last_month_followers_count.to_f %>
<div class="stat-percentage" style="color: <%= month_followers_rate > 1 ? "green" : "red" %>">
<%= month_followers_rate > 1 ? "\u25b2" : "\u25BC" %> <%= @dashboard.last_month_followers_count.positive? ? (month_followers_rate * 100).round(2) : "infinity " %>%
</div>
</div>
<div class="card">
<h4>New comments this week</h4>
<div class="featured-stat">
<%= @this_week_comments_count %>
<%= @dashboard.this_week_comments_count %>
</div>
<% week_comments_rate = @this_week_comments_count.to_f / @last_week_comments_count.to_f %>
<div class="stat-percentage" style="color: <%= week_comments_rate > 1 ? "green" : "red" %>">
<%= week_comments_rate >= 1 ? "\u25b2" : "\u25BC" %> <%= @last_week_followers_count.positive? ? (week_comments_rate * 100).round(2) : "infinity " %>%
<% week_comments_rate = @dashboard.this_week_comments_count.to_f / @dashboard.last_week_comments_count.to_f %>
<div class="stat-percentage" style="color: <%= week_comments_rate > 1 ? "green" : "red" %>">
<%= week_comments_rate > 1 ? "\u25b2" : "\u25BC" %> <%= @dashboard.last_week_followers_count.positive? ? (week_comments_rate * 100).round(2) : "infinity " %>%
</div>
</div>
<div class="card">
<h4>New comments this month</h4>
<div class="featured-stat">
<%= @this_month_comments_count %>
<%= @dashboard.this_month_comments_count %>
</div>
<% month_comments_rate = @this_month_comments_count.to_f / @last_month_comments_count.to_f %>
<div class="stat-percentage" style="color: <%= month_comments_rate > 1 ? "green" : "red" %>">
<%= month_comments_rate >= 1 ? "\u25b2" : "\u25BC" %> <%= @last_month_comments_count.positive? ? (month_comments_rate * 100).round(2) : "infinity " %>%
<% month_comments_rate = @dashboard.this_month_comments_count.to_f / @dashboard.last_month_comments_count.to_f %>
<div class="stat-percentage" style="color: <%= week_comments_rate > 1 ? "green" : "red" %>">
<%= month_comments_rate > 1 ? "\u25b2" : "\u25BC" %> <%= @dashboard.last_month_comments_count.positive? ? (month_comments_rate * 100).round(2) : "infinity " %>%
</div>
</div>
</div>
@ -73,11 +83,11 @@
<div class="charts-container">
<canvas
id="reactionsChart"
data-labels="<%= @this_week_reactions.formatted_dates %>"
data-total-count="<%= @this_week_reactions.total_per_day %>"
data-total-likes="<%= @this_week_reactions.total_by_type_per_day(type: "Reaction", category: "like") %>"
data-total-unicorns="<%= @this_week_reactions.total_by_type_per_day(type: "Reaction", category: "unicorn") %>"
data-total-readinglist="<%= @this_week_reactions.total_by_type_per_day(type: "Reaction", category: "readinglist") %>">
data-labels="<%= @dashboard.this_week_reactions.formatted_dates %>"
data-total-count="<%= @dashboard.this_week_reactions.total_per_day %>"
data-total-likes="<%= @dashboard.this_week_reactions.total_by_type_per_day(type: "Reaction", category: "like") %>"
data-total-unicorns="<%= @dashboard.this_week_reactions.total_by_type_per_day(type: "Reaction", category: "unicorn") %>"
data-total-readinglist="<%= @dashboard.this_week_reactions.total_by_type_per_day(type: "Reaction", category: "readinglist") %>">
</canvas>
</div>
<%= javascript_pack_tag "proCharts", defer: true %>
@ -87,8 +97,8 @@
<div class="charts-container">
<canvas
id="commentsChart"
data-labels="<%= @this_week_comments.formatted_dates %>"
data-total-count="<%= @this_week_comments.total_per_day %>">
data-labels="<%= @dashboard.this_week_comments.formatted_dates %>"
data-total-count="<%= @dashboard.this_week_comments.total_per_day %>">
</canvas>
</div>
</div>
@ -96,7 +106,7 @@
<h2>Activity</h2>
<h3>People who recently reacted ❤🦄🔖 to your content:</h3>
<div class="recent-reactors-container">
<% @reactors.each do |user| %>
<% @dashboard.reactors.each do |user| %>
<div class="single-article">
<a href="<%= user.path %>" class="block-link">
<h2>

View file

@ -17,18 +17,18 @@
</div>
<% if @user.org_admin && @user.organization && (params[:which].blank? || params[:which] == "organization") %>
<h1>
<a href="/dashboard" class="<%= "active" if params[:which].blank? %>">Personal</a>
<a href="/dashboard/organization" class="<%= "active" if params[:which] == "organization" %>"><%= @user.organization.name %> (<%= @user.organization.articles.size %>)</a>
<a href="/dashboard" class="rounded-btn <%= "active" if params[:which].blank? %>">Personal</a>
<a href="/dashboard/organization" class="rounded-btn <%= "active" if params[:which] == "organization" %>"><%= @user.organization.name %> (<%= @user.organization.articles.size %>)</a>
<% if @user.has_role? :pro %>
<a href="/dashboard/pro">Pro Analytics</a>
<a class="rounded-btn" href="/dashboard/pro">Pro Analytics</a>
<% end %>
</h1>
<% elsif @user.org_admin && @user.organization && (params[:which] == "organization_user_followers" || params[:which] == "user_followers") %>
<h1>
<a href="/dashboard/user_followers" class="<%= "active" if params[:which] == "user_followers" %>">Personal</a>
<a href="/dashboard/organization_user_followers" class="<%= "active" if params[:which] == "organization_user_followers" %>"><%= @user.organization.name %> (<%= @user.organization.followers_count %>)</a>
<a href="/dashboard/user_followers" class="rounded-btn <%= "active" if params[:which] == "user_followers" %>">Personal</a>
<a href="/dashboard/organization_user_followers" class="rounded-btn <%= "active" if params[:which] == "organization_user_followers" %>"><%= @user.organization.name %> (<%= @user.organization.followers_count %>)</a>
<% if @user.has_role? :pro %>
<a href="/pro">Pro Analytics</a>
<a class="rounded-btn" href="/pro">Pro Analytics</a>
<% end %>
</h1>
<% end %>

View file

@ -29,6 +29,7 @@ module PracticalDeveloper
config.autoload_paths += Dir["#{config.root}/app/observers/"]
config.autoload_paths += Dir["#{config.root}/app/black_box/"]
config.autoload_paths += Dir["#{config.root}/app/sanitizers"]
config.autoload_paths += Dir["#{config.root}/app/facades"]
config.autoload_paths += Dir["#{config.root}/lib/"]
config.active_record.observers = :article_observer, :reaction_observer, :comment_observer

View file

@ -256,6 +256,7 @@ Rails.application.routes.draw do
get "/signout_confirm" => "users#signout_confirm"
get "/dashboard" => "dashboards#show"
get "/dashboard/pro" => "dashboards#pro"
get "dashboard/pro/org/:org_id" => "dashboards#pro"
get "/dashboard/:which" => "dashboards#show",
constraints: {
which: /organization|organization_user_followers|user_followers|following_users|following|reading/