let visitors pick a day on the public page
Clicking a day shows its mode and illustration in the header, with a link back to today. The journal stays private: the calendar helper now separates interactivity from journal exposure. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
7a7fa4c095
commit
764cb542ac
6 changed files with 101 additions and 28 deletions
|
|
@ -27,6 +27,21 @@ input.bouton {
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Bouton d'action présenté comme un lien de la charte */
|
||||
button.lien {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
background: none;
|
||||
color: var(--encre);
|
||||
font: inherit;
|
||||
cursor: pointer;
|
||||
text-decoration-line: underline;
|
||||
text-decoration-color: var(--vert);
|
||||
text-decoration-thickness: 0.12em;
|
||||
text-underline-offset: 0.2em;
|
||||
}
|
||||
button.lien:hover { text-decoration-color: var(--encre); }
|
||||
|
||||
/* button_to enveloppe son bouton dans un formulaire : le garder en ligne */
|
||||
.nav form.button_to { display: inline; }
|
||||
|
||||
|
|
@ -371,6 +386,8 @@ button.jour:focus-visible {
|
|||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.public-autre-jour .detail-statut:not(:empty) { margin-right: 0.75rem; }
|
||||
|
||||
.public-historique h2 {
|
||||
margin: 2.5rem 0 0.75rem;
|
||||
font-size: 1.35rem;
|
||||
|
|
|
|||
|
|
@ -45,12 +45,13 @@ module MoodsHelper
|
|||
end
|
||||
end
|
||||
|
||||
# Un jour du calendrier : un bouton pour le propriétaire, une simple case pour les visiteurs.
|
||||
def case_jour(mood, user, interactive:, selected: false)
|
||||
# Un jour du calendrier : un bouton si on peut le choisir, sinon une simple case.
|
||||
# Le journal n'est exposé que s'il est demandé (jamais sur la page publique).
|
||||
def case_jour(mood, user, interactive:, selected: false, journal: false)
|
||||
date = mood[:recorded_at].to_date
|
||||
status = day_status(mood, user)
|
||||
mode = mode_for(mood, user)
|
||||
day_log = mood[:day_log] if interactive
|
||||
day_log = mood[:day_log] if journal
|
||||
|
||||
description = [ date_longue(date), mode&.label, libelle_statut(status), ("journal écrit" if day_log) ].compact.join(", ")
|
||||
classes = [ "jour", "jour-#{status}" ]
|
||||
|
|
|
|||
|
|
@ -1,14 +1,17 @@
|
|||
import { Controller } from "@hotwired/stimulus"
|
||||
|
||||
// Calendrier des humeurs : choisir un jour affiche son détail (illustration, mode, journal).
|
||||
// Calendrier des humeurs : choisir un jour affiche son détail (illustration, mode, et
|
||||
// sur le tableau de bord, le journal). Sert au tableau de bord comme à la page publique :
|
||||
// chaque cible est facultative.
|
||||
// Au clavier, les flèches se déplacent d'un jour (haut, bas) ou d'une semaine (gauche, droite).
|
||||
export default class extends Controller {
|
||||
static targets = [ "carte", "image", "date", "mode", "statut", "journal", "lien" ]
|
||||
static targets = [ "carte", "image", "date", "qui", "mode", "statut", "depuis", "retour", "journal", "lien" ]
|
||||
static values = { nom: String, aujourdhui: String, aujourdhuiMode: String, aujourdhuiImage: String, aujourdhuiCouleur: String }
|
||||
|
||||
connect() {
|
||||
const selectionne = this.element.querySelector(".jour[aria-pressed='true']")
|
||||
if (selectionne && new URLSearchParams(window.location.search).has("day")) {
|
||||
selectionne.scrollIntoView({ block: "center" })
|
||||
selectionne.scrollIntoView({ block: "nearest" })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -16,6 +19,11 @@ export default class extends Controller {
|
|||
this.selectionner(event.currentTarget)
|
||||
}
|
||||
|
||||
revenir() {
|
||||
const aujourdhui = this.element.querySelector(`button.jour[data-day="${this.aujourdhuiValue}"]`)
|
||||
if (aujourdhui) this.selectionner(aujourdhui)
|
||||
}
|
||||
|
||||
naviguer(event) {
|
||||
const decalages = { ArrowUp: -1, ArrowDown: 1, ArrowLeft: -7, ArrowRight: 7 }
|
||||
const decalage = decalages[event.key]
|
||||
|
|
@ -40,17 +48,42 @@ export default class extends Controller {
|
|||
jour.setAttribute("aria-pressed", "true")
|
||||
jour.tabIndex = 0
|
||||
|
||||
// Sur la page publique, aujourd'hui montre la dernière tasse posée et depuis quand
|
||||
if (jour.dataset.day === this.aujourdhuiValue && this.hasDepuisTarget) {
|
||||
this.afficherAujourdhui()
|
||||
return
|
||||
}
|
||||
|
||||
const { day, date, mode, statut, couleur, image, info } = jour.dataset
|
||||
this.carteTarget.style.setProperty("--humeur", couleur || "")
|
||||
this.imageTarget.src = image
|
||||
this.dateTarget.textContent = date
|
||||
this.modeTarget.textContent = mode || "Pas de tasse posée"
|
||||
this.statutTarget.textContent = mode ? (statut || "") : ""
|
||||
|
||||
if (this.hasDateTarget) this.dateTarget.textContent = date
|
||||
if (this.hasQuiTarget) this.quiTarget.textContent = `Le ${date} chez ${this.nomValue}`
|
||||
if (this.hasDepuisTarget) this.depuisTarget.hidden = true
|
||||
if (this.hasRetourTarget) this.retourTarget.hidden = false
|
||||
|
||||
if (this.hasJournalTarget) {
|
||||
this.journalTarget.textContent = info || this.journalTarget.dataset.vide
|
||||
this.journalTarget.classList.toggle("detail-journal-vide", !info)
|
||||
}
|
||||
if (this.hasLienTarget) {
|
||||
this.lienTarget.href = `/day_logs/edit?day=${day}`
|
||||
this.lienTarget.textContent = info ? "Modifier le journal" : "Écrire dans le journal"
|
||||
}
|
||||
|
||||
history.replaceState({}, "", `?day=${day}`)
|
||||
}
|
||||
|
||||
afficherAujourdhui() {
|
||||
this.carteTarget.style.setProperty("--humeur", this.aujourdhuiCouleurValue)
|
||||
this.imageTarget.src = this.aujourdhuiImageValue
|
||||
this.modeTarget.textContent = this.aujourdhuiModeValue
|
||||
this.quiTarget.textContent = `Aujourd’hui chez ${this.nomValue}`
|
||||
this.depuisTarget.hidden = false
|
||||
this.retourTarget.hidden = true
|
||||
history.replaceState({}, "", window.location.pathname)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<%# Calendrier des humeurs « à la GitHub » : une colonne par semaine, une ligne par jour,
|
||||
regroupé par mois. Par défaut, un bloc par année, la plus récente d'abord ;
|
||||
avec par_annee: false, tous les mois à la suite (l'année est ajoutée aux mois d'une autre année). %>
|
||||
<%# locals: (history:, user:, interactive: false, selected_date: nil, par_annee: true) -%>
|
||||
<%# locals: (history:, user:, interactive: false, journal: false, selected_date: nil, par_annee: true) -%>
|
||||
<% blocs = par_annee ? history_by_year(history) : [ [ nil, history ] ] %>
|
||||
<div class="calendrier-humeurs">
|
||||
<% blocs.each do |year, months| %>
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
<h3 class="mois-nom"><%= l(month[:month], format: year || month[:month].year == Date.current.year ? "%B" : "%B %Y") %></h3>
|
||||
<div class="mois-jours">
|
||||
<% month[:weeks].flatten.each do |mood| %>
|
||||
<%= case_jour(mood, user, interactive: interactive,
|
||||
<%= case_jour(mood, user, interactive: interactive, journal: journal,
|
||||
selected: mood[:recorded_at].to_date == selected_date) %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
<div class="tableau-calendrier">
|
||||
<h1 class="tableau-titre">Mes humeurs</h1>
|
||||
<%= render "moods/legende", user: @user, journal: true %>
|
||||
<%= render "moods/calendrier", history: history, user: @user, interactive: true, selected_date: selected_date %>
|
||||
<%= render "moods/calendrier", history: history, user: @user, interactive: true, journal: true, selected_date: selected_date %>
|
||||
</div>
|
||||
|
||||
<aside class="detail" aria-live="polite" aria-label="Jour sélectionné">
|
||||
|
|
|
|||
|
|
@ -1,30 +1,52 @@
|
|||
<% content_for :title, "Comment ça Kluk chez #{@user.username} ?" %>
|
||||
<% mode = @user.moods.last&.mode %>
|
||||
<% history = MoodCalendarService.generate_calendar(@user, start_date: 5.months.ago.beginning_of_month, end_date: Date.current) %>
|
||||
<% selected_date = (Date.parse(params[:day]) rescue Date.current) %>
|
||||
<% selected = find_day(history, selected_date) if selected_date < Date.current %>
|
||||
<% selected_date = Date.current unless selected %>
|
||||
<% aujourdhui = selected_date == Date.current %>
|
||||
<% mode_du_jour = @user.moods.last&.mode %>
|
||||
<% mode = aujourdhui ? mode_du_jour : mode_for(selected, @user) %>
|
||||
<% status = day_status(selected, @user) unless aujourdhui %>
|
||||
<% since = @user.current_mode_since %>
|
||||
|
||||
<article class="public">
|
||||
<figure class="carte-humeur carte-humeur-grande" style="<%= "--humeur: #{mode.color}" if mode %>">
|
||||
<%= image_tag (mode || Mode.new).image_url, alt: "" %>
|
||||
<article class="public" data-controller="calendrier"
|
||||
data-calendrier-nom-value="<%= @user.username %>"
|
||||
data-calendrier-aujourdhui-value="<%= Date.current.iso8601 %>"
|
||||
data-calendrier-aujourdhui-mode-value="<%= mode_du_jour&.label || "Pas de tasse posée" %>"
|
||||
data-calendrier-aujourdhui-image-value="<%= (mode_du_jour || Mode.new).image_url %>"
|
||||
data-calendrier-aujourdhui-couleur-value="<%= mode_du_jour&.color %>">
|
||||
<figure class="carte-humeur carte-humeur-grande" data-calendrier-target="carte" style="<%= "--humeur: #{mode.color}" if mode %>">
|
||||
<%= image_tag (mode || Mode.new).image_url, alt: "", data: { calendrier_target: "image" } %>
|
||||
</figure>
|
||||
|
||||
<div class="public-texte">
|
||||
<p class="public-qui">Aujourd’hui chez <%= @user.username %></p>
|
||||
<h1 class="public-mode"><%= mode&.label || "Pas encore de tasse posée" %></h1>
|
||||
<% if since %>
|
||||
<p class="public-depuis">
|
||||
<% if since == Date.current %>
|
||||
Depuis ce matin.
|
||||
<div class="public-texte" aria-live="polite">
|
||||
<p class="public-qui" data-calendrier-target="qui">
|
||||
<% if aujourdhui %>
|
||||
Aujourd’hui chez <%= @user.username %>
|
||||
<% else %>
|
||||
Depuis le <%= l(since, format: since.year == Date.current.year ? "%A %-d %B" : "%-d %B %Y") %>.
|
||||
Le <%= date_longue(selected_date) %> chez <%= @user.username %>
|
||||
<% end %>
|
||||
</p>
|
||||
<h1 class="public-mode" data-calendrier-target="mode"><%= mode&.label || "Pas de tasse posée" %></h1>
|
||||
<p class="public-depuis">
|
||||
<span data-calendrier-target="depuis" <%= "hidden" unless aujourdhui %>>
|
||||
<% if since == Date.current %>
|
||||
Depuis ce matin.
|
||||
<% elsif since %>
|
||||
Depuis le <%= l(since, format: since.year == Date.current.year ? "%A %-d %B" : "%-d %B %Y") %>.
|
||||
<% end %>
|
||||
</span>
|
||||
<span class="public-autre-jour" data-calendrier-target="retour" <%= "hidden" if aujourdhui %>>
|
||||
<span class="detail-statut" data-calendrier-target="statut"><%= libelle_statut(status) if mode %></span>
|
||||
<button type="button" class="lien" data-action="calendrier#revenir">Revenir à aujourd’hui</button>
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<section class="public-historique" aria-labelledby="public-historique-titre">
|
||||
<h2 id="public-historique-titre">Les derniers mois</h2>
|
||||
<%= render "moods/legende", user: @user %>
|
||||
<%= render "moods/calendrier", user: @user, par_annee: false,
|
||||
history: MoodCalendarService.generate_calendar(@user, start_date: 5.months.ago.beginning_of_month, end_date: Date.current) %>
|
||||
<%= render "moods/calendrier", history: history, user: @user, par_annee: false,
|
||||
interactive: true, selected_date: selected_date %>
|
||||
</section>
|
||||
</div>
|
||||
</article>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue