diff --git a/app/assets/images/unknown.jpg b/app/assets/images/unknown.jpg new file mode 100644 index 0000000..4afdfc6 Binary files /dev/null and b/app/assets/images/unknown.jpg differ diff --git a/app/models/user.rb b/app/models/user.rb index 8318888..26e0653 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -31,45 +31,6 @@ class User < ApplicationRecord end def history - history_range(Mood.first.recorded_at.to_date, Date.today) - end - - private - - def history_range(from, to) - return [] if Mood.count < 1 - - first_monday = monday_of_the_week(first_mood_date(from)) - - current_date = first_monday - current_mode = last_mode_before(current_date) - log_mood = [] - mood_range = Mood.order(:recorded_at).where(user: self, recorded_at: (first_monday..to)) - mood_range.each do |mood| - while current_date < mood.recorded_at.to_date do - log_mood << { day: current_date, mode: current_mode } - current_date += 1 - end - current_mode = mood.mode - end - - while current_date <= to.to_date do - log_mood << { day: current_date, mode: current_mode } - current_date += 1 - end - log_mood.each_slice(7).to_a - end - - def first_mood_date(from) - Mood.order(recorded_at: :asc).where("user_id = :user_id AND recorded_at >= :from", user_id: self.id, from:).first.recorded_at.to_date - end - - def monday_of_the_week(date) - date - date.wday + 1 - end - - def last_mode_before(last) - mood = Mood.where("user_id = :user_id AND recorded_at < :last", user_id: self.id, last: last).last - mood&.mode || "croisiere" + MoodCalendarService.generate_calendar(moods) end end diff --git a/app/services/mood_calendar_service.rb b/app/services/mood_calendar_service.rb new file mode 100644 index 0000000..930a357 --- /dev/null +++ b/app/services/mood_calendar_service.rb @@ -0,0 +1,72 @@ +# app/services/mood_calendar_service.rb +class MoodCalendarService + def self.generate_calendar(moods, start_date: nil, end_date: Date.current) + # Convertir la relation ActiveRecord en tableau de hash + data = moods.order(:recorded_at) + .pluck(:mode, :recorded_at) + .map { |mode, recorded_at| { mode: mode, recorded_at: recorded_at } } + + return [] if data.empty? + + # Définir start_date par défaut comme le recorded_at du premier mood + start_date ||= data.first[:recorded_at].to_date + + # Convertir en Date si ce sont des DateTime ou Time + start_date = start_date.to_date + end_date = end_date.to_date + + # Grouper par jour et garder le plus récent pour chaque jour + data_by_date = data.group_by { |d| d[:recorded_at].to_date } + .transform_values { |entries| entries.max_by { |e| e[:recorded_at] } } + + # Trouver le dernier mood avant start_date pour initialiser le guess + last_mode = data.select { |d| d[:recorded_at].to_date < start_date } + .max_by { |d| d[:recorded_at] } + &.[](:mode) + + # Générer le tableau complet avec tous les jours + complete_data = (start_date..end_date).map do |date| + if data_by_date[date] + last_mode = data_by_date[date][:mode] + data_by_date[date] + else + { mode: nil, recorded_at: date.to_datetime, guess: last_mode } + end + end + + # Regrouper par mois avec semaines commençant au premier lundi + complete_data.group_by { |d| d[:recorded_at].to_date.beginning_of_month } + .map do |month_start, month_data| + # Trouver le premier lundi du mois (à partir du 1er du mois) + first_monday = month_start + first_monday = first_monday.next_occurring(:monday) unless first_monday.monday? + + # Trouver le premier lundi du mois SUIVANT + next_month_start = month_start.next_month.beginning_of_month + next_first_monday = next_month_start + next_first_monday = next_first_monday.next_occurring(:monday) unless next_first_monday.monday? + + # Le dernier jour du mois est le dimanche précédant le premier lundi du mois suivant + month_end = next_first_monday - 1.day + + # Créer un hash pour accès rapide aux données de complete_data (qui contient déjà les guess) + data_hash = complete_data.index_by { |d| d[:recorded_at].to_date } + + # Générer tous les jours du premier lundi jusqu'au dimanche avant le prochain lundi + all_days = (first_monday..month_end).map do |date| + # Utiliser directement les données de complete_data qui ont déjà le bon guess + data_hash[date] || { mode: nil, recorded_at: date.to_datetime, guess: nil } + end + + # Grouper par semaines + weeks = all_days.group_by { |d| d[:recorded_at].to_date.beginning_of_week(:monday) } + .sort_by { |week_start, _| week_start } + .map { |_, week_moods| week_moods } + + { + month: month_start, + weeks: weeks + } + end + end +end diff --git a/app/views/moods/index.html.erb b/app/views/moods/index.html.erb index ce29b8b..4a803ed 100644 --- a/app/views/moods/index.html.erb +++ b/app/views/moods/index.html.erb @@ -38,22 +38,20 @@