From f8d4b4113d253d61d1237fa8047369d1847a0a7f Mon Sep 17 00:00:00 2001 From: IliesAllali <97601122+IliesAllali@users.noreply.github.com> Date: Sun, 18 Oct 2026 14:08:07 +0200 Subject: [PATCH] =?UTF-8?q?Mobile=20:=20parents=20s=C3=A9par=C3=A9s=20en?= =?UTF-8?q?=20pointill=C3=A9s,=20barre=20d'=C3=A9dition=20all=C3=A9g=C3=A9?= =?UTF-8?q?e,=20dates=20au=20clavier=20num=C3=A9rique=20(#82)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Deux parents d'un même enfant sans couple enregistré sont reliés en pointillés au lieu d'avoir chacun un « Inconnu » (couple propre au dessin, rien en base) ; le tri de la fratrie le reconnaît. - Barre d'édition mobile : X, « Ajouter » et « Plus » (dessin, texte, sticker, photo). Les outils s'ouvrent depuis « Plus » avec un retour, la corbeille n'apparaît que s'il y a quelque chose à effacer, l'outil actif en aplat. La barre ne passe plus sous le zoom. - Bandeau d'édition : sur téléphone, seul le bouton reste, le texte se coupait. - Dates : au-delà de 4 chiffres les barres se posent seules (12031950 → 12/03/1950), le message n'apparaît qu'en quittant le champ. - Ajouter une personne : plus d'erreur « prénom » en quittant le champ vide, le bouton reste actif et le dit à l'appui. Co-authored-by: Claude Opus 5.5 --- frontend/src/components/AddPersonPanel.jsx | 7 +- frontend/src/components/DateField.jsx | 24 +++- frontend/src/components/EditModeOverlay.css | 5 + frontend/src/components/EditSessionBar.jsx | 2 +- frontend/src/components/galaxy/constants.js | 3 + frontend/src/components/galaxy/elkLayout.js | 39 +++++- .../src/components/galaxy/elkLayout.test.js | 30 ++++- .../src/components/galaxy/siblingReorder.js | 6 +- .../components/galaxy/siblingReorder.test.js | 15 +++ .../components/navbar/ContextualNavbar.css | 6 +- .../components/navbar/ContextualNavbar.jsx | 113 ++++++++++++++---- frontend/src/i18n/en/compte.js | 5 + frontend/src/utils/dateInput.js | 7 ++ frontend/src/utils/dateInput.test.js | 16 ++- 14 files changed, 233 insertions(+), 45 deletions(-) diff --git a/frontend/src/components/AddPersonPanel.jsx b/frontend/src/components/AddPersonPanel.jsx index b23dc40..288e5fa 100644 --- a/frontend/src/components/AddPersonPanel.jsx +++ b/frontend/src/components/AddPersonPanel.jsx @@ -146,8 +146,6 @@ function AddPersonPanel({ visible, persons = [], loading = false, error = '', on }) } - const isValid = firstName.trim().length > 0 - const relationTypeLabels = { parent: t('Parent de'), child: t('Enfant de'), @@ -191,7 +189,6 @@ function AddPersonPanel({ visible, persons = [], loading = false, error = '', on className={touched.firstName && !firstName.trim() ? 'apn-input--error' : ''} value={firstName} onChange={(e) => setFirstName(e.target.value)} - onBlur={() => setTouched((prev) => ({ ...prev, firstName: true }))} placeholder={t('Marie')} autoComplete="off" aria-invalid={touched.firstName && !firstName.trim()} @@ -325,7 +322,9 @@ function AddPersonPanel({ visible, persons = [], loading = false, error = '', on - diff --git a/frontend/src/components/DateField.jsx b/frontend/src/components/DateField.jsx index a41ef4f..654b8b4 100644 --- a/frontend/src/components/DateField.jsx +++ b/frontend/src/components/DateField.jsx @@ -1,11 +1,14 @@ import { useState } from 'react' import { t } from '../i18n/index.js' -import { dateToInputText, parseDateInput } from '../utils/dateInput.js' +import { dateToInputText, formatDigitsAsDate, parseDateInput } from '../utils/dateInput.js' // Champ de date de la fiche : une année seule ou une date complète (issue #77). Le texte tapé reste tel // quel ; la valeur ne remonte qu'une fois comprise, sinon le champ le signale sans rien enregistrer. +// Le clavier numérique du téléphone n'a pas de barre oblique : au-delà de 4 chiffres, les barres se posent +// toutes seules (12031950 → 12/03/1950). Le message n'apparaît qu'en quittant le champ. export default function DateField({ id, value, onChange, placeholder, className = '' }) { const [text, setText] = useState(() => dateToInputText(value)) + const [touched, setTouched] = useState(false) const invalid = parseDateInput(text) === undefined return ( @@ -17,14 +20,23 @@ export default function DateField({ id, value, onChange, placeholder, className className={className} value={text} placeholder={placeholder || t('Année ou date')} - aria-invalid={invalid || undefined} + aria-invalid={(touched && invalid) || undefined} onChange={(e) => { - setText(e.target.value) - const parsed = parseDateInput(e.target.value) - if (parsed !== undefined) onChange(parsed) + const next = formatDigitsAsDate(e.target.value) + setText(next) + const parsed = parseDateInput(next) + if (parsed !== undefined) { + setTouched(false) + onChange(parsed) + } + }} + onBlur={() => { + const parsed = parseDateInput(text) + if (parsed === undefined) setTouched(true) + else setText(dateToInputText(parsed)) }} /> - {invalid && {t('Une année (1950) ou une date (12/03/1950)')}} + {touched && invalid && {t('Une année (1950) ou une date (12/03/1950)')}} ) } diff --git a/frontend/src/components/EditModeOverlay.css b/frontend/src/components/EditModeOverlay.css index 30edccb..850e1fc 100644 --- a/frontend/src/components/EditModeOverlay.css +++ b/frontend/src/components/EditModeOverlay.css @@ -53,6 +53,11 @@ .edit-mode-toast-text { font-size: 13px; } } +/* Téléphone : le texte se coupait en « Vous modifi… » à côté du bouton, qui suffit à lui seul */ +@media (max-width: 480px) { + .edit-mode-toast--with-submit .edit-mode-toast-text { display: none; } +} + @media (prefers-reduced-motion: reduce) { .edit-mode-toast { animation: pz-fade 160ms ease both; } } diff --git a/frontend/src/components/EditSessionBar.jsx b/frontend/src/components/EditSessionBar.jsx index 3113e39..79f9647 100644 --- a/frontend/src/components/EditSessionBar.jsx +++ b/frontend/src/components/EditSessionBar.jsx @@ -22,7 +22,7 @@ function EditSessionBar({ active, hasDraft, role = 'contributor', onDeactivate, <>