group moods by month
This commit is contained in:
parent
2667360c42
commit
a75b9242f1
4 changed files with 85 additions and 54 deletions
BIN
app/assets/images/unknown.jpg
Normal file
BIN
app/assets/images/unknown.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 37 KiB |
|
|
@ -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
|
||||
|
|
|
|||
72
app/services/mood_calendar_service.rb
Normal file
72
app/services/mood_calendar_service.rb
Normal file
|
|
@ -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
|
||||
|
|
@ -38,23 +38,21 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="logs">
|
||||
<div class="is-flex is-flex-direction-row is-flex-wrap-wrap mb-3">
|
||||
<% @history.each do |month| %>
|
||||
<div class="mr-3">
|
||||
<div> <%= I18n.l(month[:month], format: "%B %Y").capitalize %></div>
|
||||
<div class="is-flex is-flex-wrap-wrap">
|
||||
<% @history.each do |week| %>
|
||||
<% month[:weeks].each do |week| %>
|
||||
<div class="is-flex is-flex-direction-column is-flex-wrap-wrap mb-3">
|
||||
<div class="is-size-7 day">
|
||||
<% mood = week.first %>
|
||||
<% if mood[:day].day < 8 %>
|
||||
<%= l(mood[:day], format: "%b") %>
|
||||
<% week.each do |mood| %>
|
||||
<% mode = mood[:mode] || mood[:guess] || "unknown" %>
|
||||
<div data-image="<%= asset_path(mode + ".jpg") %>" data-mode="<%= mode %>" data-day="<%= l mood[:recorded_at] %>" data-action="click->mood#updateDayInfo mouseover->mood#updateDayInfo mouseleave->mood#removeFeedback" title="<%= mood[:recorded_at] %> : <%= mode %>" class="day <%= mode %>"></div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% week.each do |d| %>
|
||||
<% if mood[:mode] %>
|
||||
<div data-image="<%= asset_path(mood[:mode] + ".jpg") %>" data-mode="<%= mood[:mode] %>" data-day="<%= l mood[:day] %>" data-action="click->mood#updateDayInfo mouseover->mood#updateDayInfo mouseleave->mood#removeFeedback" title="<%= mood[:day] %> : <%= mood[:mode] %>" class="day <%= mood[:mode] %>"></div>
|
||||
<% else %>
|
||||
<div class="day"></div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<div id="end"></>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue