dawarich/app/helpers/stats_helper.rb
2025-09-12 20:11:14 +02:00

181 lines
6.3 KiB
Ruby

# frozen_string_literal: true
module StatsHelper
def distance_traveled(user, stat)
distance_unit = user.safe_settings.distance_unit
value =
if distance_unit == 'mi'
(stat.distance / 1609.34).round(2)
else
(stat.distance / 1000).round(2)
end
"#{number_with_delimiter(value)} #{distance_unit}"
end
def x_than_average_distance(stat, average_distance_this_year)
return '' if average_distance_this_year.zero?
difference = stat.distance / 1000 - average_distance_this_year
percentage = ((difference / average_distance_this_year) * 100).round
more_or_less = difference.positive? ? 'more' : 'less'
"#{percentage.abs}% #{more_or_less} than your average this year"
end
def x_than_previous_active_days(stat, previous_stat)
return '' unless previous_stat
previous_active_days = previous_stat.daily_distance.select { _1[1].positive? }.count
current_active_days = stat.daily_distance.select { _1[1].positive? }.count
difference = current_active_days - previous_active_days
return 'Same as previous month' if difference.zero?
more_or_less = difference.positive? ? 'more' : 'less'
days_word = pluralize(difference.abs, 'day')
"#{days_word} #{more_or_less} than previous month"
end
def active_days(stat)
total_days = stat.daily_distance.count
active_days = stat.daily_distance.select { _1[1].positive? }.count
"#{active_days}/#{total_days}"
end
def countries_visited(stat)
stat.toponyms.count { _1['country'] }
end
def x_than_prevopis_countries_visited(stat, previous_stat)
return '' unless previous_stat
previous_countries = previous_stat.toponyms.count { _1['country'] }
current_countries = stat.toponyms.count { _1['country'] }
difference = current_countries - previous_countries
return 'Same as previous month' if difference.zero?
more_or_less = difference.positive? ? 'more' : 'less'
countries_word = pluralize(difference.abs, 'country')
"#{countries_word} #{more_or_less} than previous month"
end
def peak_day(stat)
peak = stat.daily_distance.max_by { _1[1] }
return 'N/A' unless peak && peak[1].positive?
date = Date.new(stat.year, stat.month, peak[0])
distance_km = (peak[1] / 1000).round(2)
distance_unit = stat.user.safe_settings.distance_unit
distance_value =
if distance_unit == 'mi'
(peak[1] / 1609.34).round(2)
else
distance_km
end
text = "#{date.strftime('%B %d')} (#{distance_value} #{distance_unit})"
link_to text, map_url(start_at: date.beginning_of_day, end_at: date.end_of_day), class: 'underline'
end
def quietest_week(stat)
return 'N/A' if stat.daily_distance.empty?
# Create a hash with date as key and distance as value
distance_by_date = stat.daily_distance.to_h.transform_keys do |timestamp|
Time.at(timestamp).in_time_zone(stat.user.timezone || 'UTC').to_date
end
# Initialize variables to track the quietest week
quietest_start_date = nil
quietest_distance = Float::INFINITY
# Iterate through each day of the month to find the quietest week
start_date = distance_by_date.keys.min.beginning_of_month
end_date = distance_by_date.keys.max.end_of_month
(start_date..end_date).each_cons(7) do |week|
week_distance = week.sum { |date| distance_by_date[date] || 0 }
if week_distance < quietest_distance
quietest_distance = week_distance
quietest_start_date = week.first
end
end
return 'N/A' unless quietest_start_date
quietest_end_date = quietest_start_date + 6.days
start_str = quietest_start_date.strftime('%b %d')
end_str = quietest_end_date.strftime('%b %d')
"#{start_str} - #{end_str}"
end
def month_icon(stat)
case stat.month
when 1..2, 12 then 'snowflake'
when 3..5 then 'flower'
when 6..8 then 'tree-palm'
when 9..11 then 'leaf'
end
end
def month_color(stat)
case stat.month
when 1 then '#397bb5'
when 2 then '#5A4E9D'
when 3 then '#3B945E'
when 4 then '#7BC96F'
when 5 then '#FFD54F'
when 6 then '#FFA94D'
when 7 then '#FF6B6B'
when 8 then '#FF8C42'
when 9 then '#C97E4F'
when 10 then '#8B4513'
when 11 then '#5A2E2E'
when 12 then '#265d7d'
end
end
def month_gradient_classes(stat)
case stat.month
when 1 then 'bg-gradient-to-br from-blue-500 to-blue-800' # Winter blue
when 2 then 'bg-gradient-to-bl from-blue-600 to-purple-600' # Purple
when 3 then 'bg-gradient-to-tr from-green-400 to-green-700' # Spring green
when 4 then 'bg-gradient-to-tl from-green-500 to-green-700' # Light green
when 5 then 'bg-gradient-to-br from-yellow-400 to-yellow-600' # Spring yellow
when 6 then 'bg-gradient-to-bl from-orange-400 to-orange-600' # Summer orange
when 7 then 'bg-gradient-to-tr from-red-400 to-red-600' # Summer red
when 8 then 'bg-gradient-to-tl from-orange-600 to-red-400' # Orange-red
when 9 then 'bg-gradient-to-br from-orange-600 to-yellow-400' # Autumn orange
when 10 then 'bg-gradient-to-bl from-yellow-700 to-orange-700' # Autumn brown
when 11 then 'bg-gradient-to-tr from-red-800 to-red-900' # Dark red
when 12 then 'bg-gradient-to-tl from-blue-600 to-blue-700' # Winter dark blue
end
end
def month_bg_image(stat)
case stat.month
when 1 then image_url('backgrounds/months/anne-nygard-VwzfdVT6_9s-unsplash.jpg')
when 2 then image_url('backgrounds/months/ainars-cekuls-buAAKQiMfoI-unsplash.jpg')
when 3 then image_url('backgrounds/months/ahmad-hasan-xEYWelDHYF0-unsplash.jpg')
when 4 then image_url('backgrounds/months/lily-Rg1nSqXNPN4-unsplash.jpg')
when 5 then image_url('backgrounds/months/milan-de-clercq-YtllSzi2JLY-unsplash.jpg')
when 6 then image_url('backgrounds/months/liana-mikah-6B05zlnPOEc-unsplash.jpg')
when 7 then image_url('backgrounds/months/irina-iriser-fKAl8Oid6zM-unsplash.jpg')
when 8 then image_url('backgrounds/months/nadiia-ploshchenko-ZnDtJaIec_E-unsplash.jpg')
when 9 then image_url('backgrounds/months/gracehues-photography-AYtup7uqimA-unsplash.jpg')
when 10 then image_url('backgrounds/months/babi-hdNa4GCCgbg-unsplash.jpg')
when 11 then image_url('backgrounds/months/foto-phanatic-8LaUOtP-de4-unsplash.jpg')
when 12 then image_url('backgrounds/months/henry-schneider-FqKPySIaxuE-unsplash.jpg')
end
end
end