Skip to content

Commit

Permalink
Merge pull request #1862 from tactilenews/1861_add_basic_stats_for_admin
Browse files Browse the repository at this point in the history
Add basic stats with breakdown of channels counts
  • Loading branch information
roschaefer authored May 24, 2024
2 parents 2f2ee90 + 09d4861 commit aaab488
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 0 deletions.
8 changes: 8 additions & 0 deletions app/components/admin_stats/admin_stats.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<section style="padding: 20px">
<h1 style="padding-bottom: 20px">Stats</h1>
<p><strong>Email contributors:</strong> <%= email_contributors_count %></p>
<p><strong>Threema contributors:</strong> <%= threema_contributors_count %></p>
<p><strong>Telegram contributors:</strong> <%= telegram_contributors_count %></p>
<p><strong>Signal contributors:</strong> <%= signal_contributors_count %></p>
<p><strong>WhatsApp contributors:</strong> <%= whats_app_contributors_count %></p>
</section>
33 changes: 33 additions & 0 deletions app/components/admin_stats/admin_stats.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# frozen_string_literal: true

module AdminStats
class AdminStats < ApplicationComponent
def initialize(stats:)
super

@stats = stats
end

attr_reader :stats

def email_contributors_count
stats[:email_contributors_count]
end

def threema_contributors_count
stats[:threema_contributors_count]
end

def telegram_contributors_count
stats[:telegram_contributors_count]
end

def signal_contributors_count
stats[:signal_contributors_count]
end

def whats_app_contributors_count
stats[:whats_app_contributors_count]
end
end
end
16 changes: 16 additions & 0 deletions app/controllers/admin/stats_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# frozen_string_literal: true

module Admin
class StatsController < Admin::ApplicationController
def index
@stats = {
email_contributors_count: Contributor.with_email.count,
threema_contributors_count: Contributor.with_threema.count,
telegram_contributors_count: Contributor.with_telegram.count,
signal_contributors_count: Contributor.with_signal.count,
whats_app_contributors_count: Contributor.with_whats_app.count
}
render AdminStats::AdminStats.new(stats: @stats)
end
end
end
7 changes: 7 additions & 0 deletions app/dashboards/stat_dashboard.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

require 'administrate/custom_dashboard'

class StatDashboard < Administrate::CustomDashboard
resource 'Stats' # used by administrate in the views
end
6 changes: 6 additions & 0 deletions app/models/contributor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ class Contributor < ApplicationRecord
tag_list.blank? ? all : tagged_with(tag_list)
}

scope :with_email, -> { where.not(email: nil) }
scope :with_threema, -> { where.not(threema_id: nil) }
scope :with_telegram, -> { where.not(telegram_id: nil) }
scope :with_signal, -> { where.not(signal_phone_number: nil, signal_onboarding_completed_at: nil) }
scope :with_whats_app, -> { where.not(whats_app_phone_number: nil) }

before_validation do
self.email = nil if email.blank?
self.threema_id = nil if threema_id.blank?
Expand Down
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
resources :delayed_jobs, only: %i[index show destroy]
resources :business_plans, only: %i[index show edit update]
resources :organizations, only: %i[index show edit update]
resources :stats, only: [:index]
end
end

Expand Down
35 changes: 35 additions & 0 deletions spec/factories/contributors.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# frozen_string_literal: true

# rubocop:disable Metrics/BlockLength
FactoryBot.define do
factory :contributor do
first_name { Faker::Name.first_name }
Expand All @@ -15,5 +16,39 @@
)
end
end

trait :threema_contributor do
after(:build) do |contributor|
contributor.email = nil
contributor.threema_id = Faker::String.random(length: 8)
end
end

trait :telegram_contributor do
after(:build) do |contributor|
contributor.email = nil
contributor.telegram_id = Faker::Number.number(digits: 9)
end
end

trait :signal_contributor do
after(:build) do |contributor|
contributor.email = nil
contributor.signal_phone_number = Faker::PhoneNumber.cell_phone_in_e164
contributor.signal_onboarding_completed_at = Time.current
end
end

trait :whats_app_contributor do
after(:build) do |contributor|
contributor.email = nil
contributor.whats_app_phone_number = Faker::PhoneNumber.cell_phone_in_e164
end
end

trait :skip_validations do
to_create { |instance| instance.save(validate: false) }
end
end
end
# rubocop:enable Metrics/BlockLength
28 changes: 28 additions & 0 deletions spec/system/admin/stats_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe 'Stats' do
context 'as admin' do
let(:user) { create(:user, admin: true) }
let(:mock_validator) { instance_double(ThreemaValidator) }

before do
create_list(:contributor, 3)
create_list(:contributor, 2, :threema_contributor, :skip_validations)
create_list(:contributor, 4, :telegram_contributor)
create_list(:contributor, 6, :signal_contributor)
create_list(:contributor, 12, :whats_app_contributor)
end

it 'admin edits contributor' do
visit admin_stats_path(as: user)

expect(page).to have_content('Email contributors: 3')
expect(page).to have_content('Threema contributors: 2')
expect(page).to have_content('Telegram contributors: 4')
expect(page).to have_content('Signal contributors: 6')
expect(page).to have_content('WhatsApp contributors: 12')
end
end
end

0 comments on commit aaab488

Please sign in to comment.