From af6ad2b2cf2e5c0a9691ec88a8e4c9c501a82c0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=20Rodr=C3=ADguez?= Date: Sun, 2 Jun 2024 18:14:01 +0200 Subject: [PATCH] feat: show statistics in the dashboard front --- .../dashboard_statistic_component.html.erb | 5 +++ .../dashboard_statistic_component.rb | 25 +++++++++++ .../dashboard/dashboard_controller.rb | 9 ++++ app/services/plausible/client.rb | 2 +- app/services/plausible/integration.rb | 11 +++++ app/services/plausible/month_analyzer.rb | 41 +++++++++++++++++++ app/views/dashboard/dashboard/index.html.erb | 16 ++++++++ 7 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 app/components/dashboard/dashboard_statistic_component.html.erb create mode 100644 app/components/dashboard/dashboard_statistic_component.rb create mode 100644 app/services/plausible/month_analyzer.rb diff --git a/app/components/dashboard/dashboard_statistic_component.html.erb b/app/components/dashboard/dashboard_statistic_component.html.erb new file mode 100644 index 00000000..9ea7ca44 --- /dev/null +++ b/app/components/dashboard/dashboard_statistic_component.html.erb @@ -0,0 +1,5 @@ +
+

<%= label %>

+

<%= value %> +

(<%= increment %>% to previous)

+
diff --git a/app/components/dashboard/dashboard_statistic_component.rb b/app/components/dashboard/dashboard_statistic_component.rb new file mode 100644 index 00000000..d8c81518 --- /dev/null +++ b/app/components/dashboard/dashboard_statistic_component.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module Dashboard + class DashboardStatisticComponent < ViewComponent::Base + def initialize(label:, value:, increment:) + @label = label + @value = value + @increment = increment + end + + private + + attr_reader :label, :value, :increment + + def pill_class + if increment > 0 + 'text-bg-success' + elsif increment < 0 + 'text-bg-warning' + else + 'text-bg-secondary' + end + end + end +end diff --git a/app/controllers/dashboard/dashboard_controller.rb b/app/controllers/dashboard/dashboard_controller.rb index cce3a8dc..5128f23a 100644 --- a/app/controllers/dashboard/dashboard_controller.rb +++ b/app/controllers/dashboard/dashboard_controller.rb @@ -12,6 +12,15 @@ def index @topics = Topic.count @users = User.count @opinions = Opinion.count + @statistics = fetch_statistics + end + + private + + def fetch_statistics + Plausible::Integration.last_30_days(true) + rescue Net::HTTPError + nil end end end diff --git a/app/services/plausible/client.rb b/app/services/plausible/client.rb index 97823599..7e143c73 100644 --- a/app/services/plausible/client.rb +++ b/app/services/plausible/client.rb @@ -43,7 +43,7 @@ def client def timeseries_params yesterday = DateTime.current.yesterday - sixty_days_ago = yesterday - 60.days + sixty_days_ago = yesterday - 59.days # one less because otherwise it is one more date = "#{sixty_days_ago.strftime('%F')},#{yesterday.strftime('%F')}" { site_id:, period: 'custom', date:, metrics: 'visits,pageviews,visit_duration' } diff --git a/app/services/plausible/integration.rb b/app/services/plausible/integration.rb index 2469578b..3d550d5e 100644 --- a/app/services/plausible/integration.rb +++ b/app/services/plausible/integration.rb @@ -6,6 +6,17 @@ def self.client Plausible::Integration.new.client end + def self.last_30_days(compare = false) + data = Rails.cache.fetch('plausible:last_30_days', expires_in: 2.hours) do + client.time_series + end + if compare + Plausible::MonthAnalyzer.new(data).month_compare + else + Plausible::MonthAnalyzer.new(data).month_forecast + end + end + def client Plausible::Client.new(site_id, api_key) end diff --git a/app/services/plausible/month_analyzer.rb b/app/services/plausible/month_analyzer.rb new file mode 100644 index 00000000..bbf5ee38 --- /dev/null +++ b/app/services/plausible/month_analyzer.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +module Plausible + class MonthAnalyzer + def initialize(value) + @value = value + @this_month = @value[30..] + @previous_month = @value[0..29] + end + + def month_compare + this_sum = month_forecast + prev_sum = reduce_month(previous_month) + %i[visits pageviews visit_duration].index_with { |k| fold_comparison(this_sum, prev_sum, k) } + end + + def month_forecast + reduce_month(this_month) + end + + private + + attr_reader :value, :this_month, :previous_month + + def fold_comparison(this, previous, key) + delta = (((this[key].to_f / previous[key]) - 1) * 100).round + { value: this[key], previous: previous[key], delta: delta } + end + + def reduce_month(month) + accum = month.reduce(Hash::new(0)) do |total, day| + duration = day["visit_duration"] * day["visits"] + { pageviews: total[:pageviews] + day["pageviews"], + visit_duration: total[:visit_duration] + duration, + visits: total[:visits] + day["visits"] } + end + accum[:visit_duration] = (accum[:visit_duration].to_f / accum[:visits]).round + accum + end + end +end diff --git a/app/views/dashboard/dashboard/index.html.erb b/app/views/dashboard/dashboard/index.html.erb index db31b31c..46886cb5 100644 --- a/app/views/dashboard/dashboard/index.html.erb +++ b/app/views/dashboard/dashboard/index.html.erb @@ -35,6 +35,22 @@
+ +
+
+ Últimos 30 días +
+
+ <% if @statistics.present? %> + <%= render Dashboard::DashboardStatisticComponent.new(label: 'Sesiones', value: @statistics[:visits][:value], increment: @statistics[:visits][:delta]) %> + <%= render Dashboard::DashboardStatisticComponent.new(label: 'Páginas', value: @statistics[:pageviews][:value], increment: @statistics[:pageviews][:delta]) %> + <%= render Dashboard::DashboardStatisticComponent.new(label: 'Tiempo', value: running_time(@statistics[:visit_duration][:value]), increment: @statistics[:visit_duration][:delta]) %> + <% else %> +

No se ha podido consultar el servicio de estadísticas externas.

+ <% end %> +
+
+
Acciones rápidas