Decimal Python → string JSON causait TypeError: z.toFixed is not a function
dans NoteCard (title attribute de l'icône GPS). Tous les champs gps_lat/gps_lon
passent maintenant en float | None dans les schémas Pydantic.
v0.5.3
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ImportError au démarrage du backend : ALLOWED_AUDIO_TYPES avait été renommé
en ALLOWED_AUDIO_PREFIXES dans services/media.py mais l'import dans api/media.py
n'avait pas été mis à jour.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sans cet attribut, iOS affiche le menu natif (Prendre une photo / Bibliothèque /
Fichiers) et Android propose un sélecteur de source.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
navigator.geolocation est undefined sur HTTP hors localhost (contexte non sécurisé).
- Message d'erreur visible selon le cas (permission, HTTPS, timeout)
- Fallback : deux champs lat/lon s'affichent automatiquement
- TodoForm : bouton GPS toujours actif (plus disabled sur navigator.geolocation)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- TopBar enrichi : icône maison + nom + version (gauche), thème + compte (droite)
- Bouton compte désactivé (placeholder pour future auth multi-utilisateurs)
- Suppression de la carte HomeHub redondante sur la page d'accueil
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
BottomSheet.tsx
- visualViewport API : calcule la hauteur du clavier en temps réel
- bottom: keyboardOffset → le sheet monte exactement au-dessus du clavier
- maxHeight s'adapte à l'espace visible restant
- border-radius passe à 16px partout quand le clavier est ouvert
- Transition douce 0.15s sur bottom/maxHeight/border-radius
ShoppingPage.tsx
- type="search" sur le champ de recherche → supprime la suggestion URL iOS
dans la barre QuickType du clavier
- autoFocus → clavier s'ouvre automatiquement à l'ouverture du sheet
v0.5.1
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ThemeContext
- ThemeMode dark/light/system persisté en localStorage
- fontScale 0.8–1.4 appliqué via CSS zoom sur <html>
- Écoute prefers-color-scheme pour le mode système
index.html
- Script anti-flash : applique thème et zoom synchrone avant le premier rendu
Layout
- TopBar fixe 44px : bouton icône qui cycle dark→light→system→dark
- Contenu décalé de 44px vers le bas
ConfigPage (/config)
- Sélecteur de thème (3 boutons avec icônes)
- Slider taille de texte avec aperçu temps réel
- Bouton Réinitialiser
HomePage
- Tuile Paramètres (fa-sliders) → /config
TodoForm
- Paste Ctrl+V pour ajouter une photo (même mécanique que CatalogueModal)
- Indice visuel "ou Ctrl+V"
v0.5.0
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Cochée par défaut à la création (aucune date soumise).
Décochée si la tâche éditée a déjà une date (champ date pré-rempli).
Décocher affiche le sélecteur de date ; cocher le masque et efface la date.
v0.4.14
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Écoute l'événement paste sur window quand le formulaire est ouvert.
Si le presse-papier contient une image, déclenche le même upload
que le bouton fichier. Indice visuel "ou Ctrl+V" affiché sous le bouton.
Les deux méthodes (fichier + coller) coexistent.
v0.4.13
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
La règle ~* \.(webp|...) prenait priorité sur /media/ et servait
les images uploadées depuis le HTML statique au lieu de les proxifier
vers le backend — causant un 404 sur toutes les photos d'articles.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Migration 006 : colonne tags TEXT[] sur shopping.products
- Modèle SQLAlchemy + schémas Pydantic mis à jour (ProductCreate/Update/Response)
- Interface TypeScript Product/ProductCreate/ProductUpdate avec tags?: string[]
- CatalogueModal : chip input (Entrée/virgule pour ajouter, clic pour supprimer, Backspace pour retirer le dernier)
- Recherche dans le catalogue et le bottom sheet étendue aux tags (insensible aux accents)
- Tags affichés en pills dans la liste du catalogue
v0.4.12
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Le backend utilisait ILIKE (insensible à la casse uniquement) — "iles" ne
trouvait pas "Îles flottantes". Passage au filtrage client avec matchesSearch
(normalize NFD) identique au bottom sheet. Charge tous les produits une fois
puis filtre sur name, brand et category sans aller-retour serveur.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Le cercle de fond était visible derrière le FAB — deux cercles superposés.
Slot conservé (flex, positionnement) mais sans visuel propre.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Avec 119 articles en base et limit=50, les articles en fin de liste
alphabétique (Îles flottantes, Éponge…) n'apparaissaient pas dans
le bottom sheet. Limite portée à 500 côté backend ET frontend.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- CatalogueModal : cleanForm() capitalise désormais le nom avant envoi API
(création et modification d'article)
- Migration 005 : met à jour shopping.products.name et
shopping.list_items.custom_name pour capitaliser les données existantes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Les produits créés/modifiés via le modal Catalogue n'apparaissaient pas
dans le bottom sheet car products n'était chargé qu'au montage de la page.
refreshProducts() est désormais appelé à chaque fermeture du CatalogueModal.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fermeture incorrecte du .map(s => { return (...) }) — le } de la
fonction arrow était absent, causant une erreur TS1005 au build.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- ActionButtonContext : contexte React permettant aux pages d'injecter
leur bouton action dans la navbar (Shopping=fa-cart-plus, Todos/Notes=+)
- BottomNav : 5e slot dédié avec dock circulaire visuel permanent ;
bouton rendu 10px au-dessus du centre du slot (effet soulevé)
- Layout : ActionButtonProvider + overflow visible sur le conteneur nav
- Pages : useEffect enregistre/vide le bouton action — plus de FAB flottant
sur le contenu, liste entièrement visible
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
FAB déplacé sur la barre de nav (bottom: 10px) au lieu de flotter
au-dessus de la liste — liste entièrement visible sur Shopping,
Todos et Notes. paddingBottom liste réduit à 64px (hauteur nav seule).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Bug: décrémentation à 0 d'un article pré-chargé (existingItemId) conserve
la sélection à qty=0 (marqué pour DELETE) → bouton ✓ devient accessible
Visuel: fond rouge + barré + opacité 0.6 pour les articles à supprimer
- UX: première lettre en majuscule auto lors de l'ajout d'un article libre
- UX: FAB remplace '+' par fa-cart-plus pour mieux signifier l'ajout à la liste
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Boutons Annuler (fa-xmark, outline err) et Valider (fa-check, ok)
déplacés en haut du sheet, pill shape, touch target 48px
- Suppression du bouton sticky en bas
- zIndex sheet 70 > tab bar 50 : bottom sheet couvre la nav
- maxHeight 85dvh → 92dvh pour exploiter l'espace libéré
- Poignée de drag supprimée
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- openAddSheet() pré-charge les articles non cochés de la liste courante
(qty existante, PATCH si modifiée / POST si nouvel article)
- Toggle "Ajouter au catalogue" sur les articles libres nouvellement saisis
(coché par défaut, créé via createProduct puis lié en product_id)
- Bouton "Confirmer (N)" comptant uniquement les actions réelles
(new items + existing avec qty modifiée)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- QtyControls: boutons +/- design system (var(--ok)/var(--err)/var(--bg-5))
- qty=0 → article non sélectionné, seul "+" visible (var(--ok) plein)
- qty>0 → fond teinté vert, "−" + valeur mono + "+" ; "−" retire si qty atteint 1
- Quantité transmise à addItem lors de la confirmation
- Articles libres : même comportement +/- en tête de liste
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- BottomSheet.tsx: panneau ancré en bas, max-height 85dvh (clavier-aware),
centré sur laptop (max-width 600px), backdrop, drag handle visuel
- ShoppingPage: remplace le modal centré par le BottomSheet multi-select
· sélection multiple avec toggle (cercle vert + fond teinté)
· articles libres affichés en tête avec tag "article libre"
· bouton "Ajouter (N)" sticky, grisé à 0 sélection
· pas d'autoFocus → liste visible d'emblée, clavier fermé
· FAB + masqué quand le sheet est ouvert
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- autocomplete/autocorrect/autocapitalize off + spellCheck false sur le
champ de recherche → supprime la barre de suggestions iOS et le popup autofill
- maxHeight liste: min(240px, 35dvh) → reste visible quand le clavier est ouvert
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- user-select:none global (index.css) + reset sur input/textarea/select
- ItemRow: swipe gauche → édition (fond bleu), suppression long press,
bouton ✕ toujours visible sur mobile
- SwipeableRow: prop onSwipeLeft, révèle rightContent entre seuil/2 et seuil,
déclenche onSwipeLeft au seuil complet
- TodosPage: onSwipeLeft → édition (remplace double-tap)
- inputMode=decimal sur tous les champs quantité et prix
- formatQty: affiche "2" au lieu de "2.000"
- Versionnage: __APP_VERSION__ injecté par Vite depuis package.json v0.4.0
- HomePage: version affichée à côté du titre (v0.4.0)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Backend :
- Migration 004 : last_purchased_at (DATE) + avg_interval_days (NUMERIC)
sur shopping.products
- update_item : met à jour les stats au premier cochage d'un article
lié à un produit (moyenne mobile exp. 70/30)
- ProductResponse expose les deux nouveaux champs
Frontend :
- ItemRow : long press 500ms → onEdit() (mobile) ; crayon + croix (laptop)
- ShoppingPage : modal édition quantité/unité, état editingItem
- api/shopping.ts : Product inclut last_purchased_at + avg_interval_days
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Quand un article tapé n'existe pas dans le catalogue et qu'aucun produit
n'est sélectionné, une case "Ajouter au catalogue" apparaît (cochée par
défaut). Si cochée, le produit est créé via POST /api/shopping/products
avant l'ajout à la liste, avec l'unité pré-remplie si saisie.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Upload photo (context=product → thumbnail 150×150) dans CatalogueModal
- Miniature affichée dans la liste et dans le formulaire
- Schémas ProductCreate/Update/Response exposent image_path + thumbnail_path
- Backend sert /media/* via StaticFiles (FastAPI)
- Proxy /media → backend dans vite.config et nginx.conf
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Supprime le bouton "Nouvelle tâche" laptop, remplace par le même FAB
circulaire que mobile — position adaptée (bottom: 72px mobile, 24px laptop).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Liste scrollable alphabétique filtrée en temps réel, sélection en un tap
(pré-remplit l'unité), ou saisie libre si article hors catalogue.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- UX : vue par défaut = liste en cours, landing si pas de liste (+ vert +
baguette magique), suppression des vues "listes" et "mode magasin" séparés
- Articles cochés barrés et déplacés en bas, tri alphabétique par section
- Nom de liste auto avec numéro de semaine ISO (S21 2026)
- Wake lock activé dès qu'une liste est ouverte
- CRUD boutiques : POST/PATCH/DELETE /stores + modal Boutiques
- CRUD articles : POST/PATCH/DELETE /products + modal Catalogue
- Champs enrichis produits : description, prix, quantité/unité, boutique défaut
- Champs enrichis boutiques : url, store_type (alimentaire, bricolage…)
- Migration 003 : nouveaux champs en base
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- TodoForm : domaines en chips multi-select colorés, priorité en 3 boutons
colorés (haute/moyenne/basse), date initialisée à aujourd'hui, description
et URL toujours visibles, boutons photo et GPS
- TodosPage : suppression filtres domaine/priorité, tags colorés par domaine
dans les lignes, userSelect:none, groupage multi-domaines
- todos.ts : ajout domains[], photo_path, gps_lat/lng dans les interfaces TS
- index.html : viewport maximum-scale=1.0, user-scalable=no
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>