Enable Org Pro Dashboard View (#2060)
This commit is contained in:
parent
6524817621
commit
8a3d3ae765
10 changed files with 145 additions and 60 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
7
app/facades/dashboard.rb
Normal 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
|
||||
0
app/facades/dashboards/pro.rb
Normal file
0
app/facades/dashboards/pro.rb
Normal file
71
app/facades/pro.rb
Normal file
71
app/facades/pro.rb
Normal 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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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 %>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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/
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue