diff --git a/app/controllers/admin/stats_controller.rb b/app/controllers/admin/stats_controller.rb index 44fc9b88..37d8db10 100644 --- a/app/controllers/admin/stats_controller.rb +++ b/app/controllers/admin/stats_controller.rb @@ -1,37 +1,11 @@ class Admin::StatsController < ApplicationController def index - @dashboard = AdminStats.new - @users = User.all + @stats = Rails.cache.fetch("admin_stats", expires_in: 1.hour) do + AdminStatsService.new.generate_stats + end - # Preload data for charts - @users_by_week = @dashboard.users_by_week_since(90.days.ago) - @pro_users_by_week = @dashboard.pro_users_by_week_since(90.days.ago) - @entries_by_week = @dashboard.entries_by_week_since(90.days.ago) - @emails_sent_by_month = @dashboard.emails_sent_by_month_since(90.days.ago) - @payments_by_month = @dashboard.payments_by_month(1.year.ago) - - # Use counter cache for frequently accessed counts - @all_count = Entry.count - @photos_count = Entry.only_images.count - @ai_entries_count = Entry.with_ai_responses.count - - # User statistics - @total_users = @users.count - @pro_users = @users.pro_only.count - @monthly_users = @users.monthly.count - @yearly_users = @users.yearly.count - @forever_users = @users.forever.count - @payhere_users = @users.payhere_only.count - @gumroad_users = @users.gumroad_only.count - @paypal_users = @users.paypal_only.count - @referral_users = @users.referrals - - # Email statistics - @emails_sent_total = @users.sum(:emails_sent) - @emails_received_total = @users.sum(:emails_received) - - # Paginate large datasets - @upgrades = @dashboard.upgraded_users_since(90.days.ago).page(params[:upgrades_page]).per(20) - @bounces = @dashboard.bounced_users_since(90.days.ago).page(params[:bounces_page]).per(20) + @upgrades = User.pro.order(created_at: :desc).page(params[:upgrades_page]).per(20) + @bounces = User.with_bounced_emails.order(updated_at: :desc).page(params[:bounces_page]).per(20) + @free_users_recent = User.free.where('created_at > ?', 90.days.ago).order(created_at: :desc).page(params[:free_users_page]).per(20) end end diff --git a/app/services/admin_stats_service.rb b/app/services/admin_stats_service.rb new file mode 100644 index 00000000..d206a3c9 --- /dev/null +++ b/app/services/admin_stats_service.rb @@ -0,0 +1,28 @@ +class AdminStatsService + def generate_stats + { + all_count: Entry.count, + photos_count: Entry.with_photos.count, + ai_entries_count: Entry.ai_generated.count, + ai_users_count: User.with_ai_entries.count, + total_users: User.count, + pro_users: User.pro.count, + users: { + monthly: User.pro.monthly.count, + yearly: User.pro.yearly.count, + forever: User.pro.forever.count, + payhere_only: User.pro.payhere_only.count, + gumroad_only: User.pro.gumroad_only.count, + paypal_only: User.pro.paypal_only.count + }, + referral_users: User.with_referrals.group(:referrer).count, + emails_sent_total: User.sum(:emails_sent), + emails_received_total: User.sum(:emails_received), + users_by_week: User.group_by_week(:created_at, last: 90.days).count, + pro_users_by_week: User.pro.group_by_week(:created_at, last: 90.days).count, + entries_by_week: Entry.group_by_week(:created_at, last: 90.days).count, + emails_sent_by_month: User.group_by_month(:created_at, last: 90.days).sum(:emails_sent), + payments_by_month: Payment.group_by_month(:created_at, last: 1.year).sum(:amount) + } + end +end diff --git a/app/views/admin/stats.html.haml b/app/views/admin/stats.html.haml deleted file mode 100644 index 2022cf73..00000000 --- a/app/views/admin/stats.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -.col-md-12 - %hr -.col-md-12 - %h3 #{pluralize(format_number(@bounces.total_count), "user")} from the last 90 days has had emails bouncing - = render partial: 'bounces_table', locals: { bounces: @bounces, dashboard: @dashboard } - = paginate @bounces, param_name: 'bounces_page' diff --git a/app/views/admin/stats/index.html.haml b/app/views/admin/stats/index.html.haml index 532a389b..f7513db6 100644 --- a/app/views/admin/stats/index.html.haml +++ b/app/views/admin/stats/index.html.haml @@ -12,20 +12,20 @@ .col-md-3 %strong All Entries .col-md-2 - %strong #{format_number(@all_count)} + %strong #{format_number(@stats[:all_count])} .row .col-md-3 %strong All Entries with Photos .col-md-2 =link_to admin_photos_path do - %strong #{format_number(@photos_count)} - %span{style: "margin-left: 10px;"} #{number_to_percentage(@photos_count.to_f/@all_count.to_f*100, precision: 0)} + %strong #{format_number(@stats[:photos_count])} + %span{style: "margin-left: 10px;"} #{number_to_percentage(@stats[:photos_count].to_f/@stats[:all_count].to_f*100, precision: 0)} .row .col-md-3 %strong All Entries using DabbleMeGPT .col-md-2 - %strong #{format_number(@ai_entries_count)} - %span{style: "margin-left: 10px;"} #{format_number(@ai_users_count)} users + %strong #{format_number(@stats[:ai_entries_count])} + %span{style: "margin-left: 10px;"} #{format_number(@stats[:ai_users_count])} users .col-md-12 %hr @@ -35,34 +35,34 @@ .col-md-3 %strong All Users .col-md-2 - %strong #{format_number(@total_users)} + %strong #{format_number(@stats[:total_users])} .row .col-md-3 %strong Pro / Free .col-md-2 - %strong #{format_number(@pro_users)} - %span{style: "margin-left: 10px;"} #{number_to_percentage(@pro_users.to_f/@total_users.to_f*100, precision: 1)} + %strong #{format_number(@stats[:pro_users])} + %span{style: "margin-left: 10px;"} #{number_to_percentage(@stats[:pro_users].to_f/@stats[:total_users].to_f*100, precision: 1)} .col-md-2 - %strong #{format_number(@total_users - @pro_users)} + %strong #{format_number(@stats[:total_users] - @stats[:pro_users])} .row .col-md-3 %strong Pro Monthly / Yearly / Forevers .col-md-2 - %strong #{format_number(@users.monthly)} + %strong #{format_number(@stats[:users][:monthly])} .col-md-2 - %strong #{format_number(@users.yearly)} - %span{style: "margin-left: 10px;"} #{number_to_percentage(@users.yearly.to_f/@pro_users.to_f*100, precision: 1)} + %strong #{format_number(@stats[:users][:yearly])} + %span{style: "margin-left: 10px;"} #{number_to_percentage(@stats[:users][:yearly].to_f/@stats[:pro_users].to_f*100, precision: 1)} .col-md-2 - %strong #{format_number(@users.forever)} + %strong #{format_number(@stats[:users][:forever])} .row .col-md-3 %strong Pro Stripe / Gumroad / Paypal .col-md-2 - %strong #{format_number(@users.payhere_only)} + %strong #{format_number(@stats[:users][:payhere_only])} .col-md-2 - %strong #{format_number(@users.gumroad_only)} + %strong #{format_number(@stats[:users][:gumroad_only])} .col-md-2 - %strong #{format_number(@users.paypal_only)} + %strong #{format_number(@stats[:users][:paypal_only])} .col-md-12 %hr @@ -72,13 +72,13 @@ .col-md-3 %strong Referrals .col-md-2 - %strong #{format_number(@referral_users.size)} - - @referral_users.pluck(:referrer).uniq.each do |ref| + %strong #{format_number(@stats[:referral_users].size)} + - @stats[:referral_users].pluck(:referrer).uniq.each do |ref| .row .col-md-3 = ref .col-md-2 - #{format_number(@referral_users.where(referrer: ref).size)} + #{format_number(@stats[:referral_users].where(referrer: ref).size)} .col-md-12 %hr @@ -86,13 +86,13 @@ .col-md-3 %strong Total Emails Sent .col-md-3 - - emails_sent_total = @users.sum(:emails_sent) + - emails_sent_total = @stats[:emails_sent_total] %strong= format_number(emails_sent_total) .clearfix .col-md-3 %strong Total Emails Received .col-md-2 - - emails_received_total = @users.sum(:emails_received) + - emails_received_total = @stats[:emails_received_total] %strong= format_number(emails_received_total) %span{style: "margin-left: 10px;"} #{number_to_percentage(emails_received_total.to_f/emails_sent_total.to_f*100, precision: 0)} @@ -101,27 +101,27 @@ .col-md-12 %h3 Sign ups over the last 90 days - = line_chart @users_by_week, discrete: true + = line_chart @stats[:users_by_week], discrete: true %br .col-md-12 %h3 Pro Upgrades over the last 90 days - = line_chart @pro_users_by_week, discrete: true + = line_chart @stats[:pro_users_by_week], discrete: true %br .col-md-12 %h3 Entries over the last 90 days - = line_chart @entries_by_week, discrete: true + = line_chart @stats[:entries_by_week], discrete: true %br .col-md-12 %h3 Emails over the last 90 days - = line_chart @emails_sent_by_month, discrete: true + = line_chart @stats[:emails_sent_by_month], discrete: true %br .col-md-12 %h3 Payments by month over the last year - = column_chart @payments_by_month, discrete: true + = column_chart @stats[:payments_by_month], discrete: true %br .col-md-12