From 547e0e8437402f9e56ad85a28fcce5e081eb0e3c Mon Sep 17 00:00:00 2001 From: Gwadaking Date: Tue, 14 Apr 2026 17:34:26 -0400 Subject: [PATCH] =?UTF-8?q?fix:=20l=C3=A9gende=20en=20popup=20mobile=20+?= =?UTF-8?q?=20manifest=20PWA=20sans=20screenshots?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- frontend/public/manifest.json | 10 +- frontend/public/sw.js | 8 +- frontend/src/components/Legend/Legend.css | 114 +++++++++++++++++++++- frontend/src/components/Legend/Legend.jsx | 40 +++++++- 4 files changed, 153 insertions(+), 19 deletions(-) diff --git a/frontend/public/manifest.json b/frontend/public/manifest.json index 004e472..eb7a484 100644 --- a/frontend/public/manifest.json +++ b/frontend/public/manifest.json @@ -23,13 +23,5 @@ "purpose": "any maskable" } ], - "screenshots": [ - { - "src": "/assets/logo-radarsargasses971.png", - "sizes": "512x512", - "type": "image/png", - "form_factor": "narrow", - "label": "Carte radar sargasses Guadeloupe" - } - ] + "categories": ["navigation", "weather"] } diff --git a/frontend/public/sw.js b/frontend/public/sw.js index bc4e50d..e3fa21c 100644 --- a/frontend/public/sw.js +++ b/frontend/public/sw.js @@ -1,9 +1,9 @@ // Service Worker — Sargasse-Sentry // fetch handler requis par Chrome pour le critère d'installabilité PWA -self.addEventListener('fetch', (event) => { - // Pass-through : on ne met rien en cache pour l'instant (app data-driven, pas offline) - event.respondWith(fetch(event.request)); -}); +// Fetch handler vide — requis par Chrome pour l'installabilité PWA. +// Pas de mise en cache : les données sont temps-réel. +// On ne fait PAS de respondWith pour éviter les erreurs sur les tiles cross-origin. +self.addEventListener('fetch', () => {}); self.addEventListener('push', (event) => { if (!event.data) return; diff --git a/frontend/src/components/Legend/Legend.css b/frontend/src/components/Legend/Legend.css index df9b1e1..f02dc7f 100644 --- a/frontend/src/components/Legend/Legend.css +++ b/frontend/src/components/Legend/Legend.css @@ -1,3 +1,4 @@ +/* ── Légende — desktop : toujours visible ── */ .legend { position: absolute; bottom: 110px; @@ -13,14 +14,30 @@ box-shadow: 4px 4px 0px #333; } +.legend__header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 2px; +} + .legend__title { font-family: 'Fredoka One', cursive; font-size: 13px; color: #1a1a2e; - margin-bottom: 2px; letter-spacing: 0.03em; } +/* Croix cachée sur desktop */ +.legend__close { + display: none; +} + +/* Bouton toggle caché sur desktop */ +.legend__toggle { + display: none; +} + .legend__item { display: flex; align-items: center; @@ -62,6 +79,99 @@ .legend__dot--medium { background: #f59e0b; } .legend__dot--high { background: #ef4444; } +/* ── Mobile ── */ @media (max-width: 480px) { - .legend { bottom: auto; top: 68px; left: 10px; } + /* Bouton toggle flottant en bas à gauche */ + .legend__toggle { + display: flex; + align-items: center; + justify-content: center; + position: absolute; + bottom: max(60px, calc(60px + env(safe-area-inset-bottom))); + left: max(16px, calc(16px + env(safe-area-inset-left))); + width: 36px; + height: 36px; + background: #fffbf0; + border: 2.5px solid #333; + border-radius: 50%; + font-size: 16px; + cursor: pointer; + box-shadow: 3px 3px 0px #333; + z-index: 15; + transition: transform .1s, box-shadow .1s; + } + .legend__toggle:hover { + transform: translate(-2px, -2px); + box-shadow: 5px 5px 0px #333; + } + + /* Backdrop semi-transparent */ + .legend__backdrop { + position: fixed; + inset: 0; + background: rgba(0,0,0,0.25); + z-index: 19; + } + + /* Légende cachée par défaut sur mobile */ + .legend { + position: fixed; + bottom: max(20px, calc(20px + env(safe-area-inset-bottom))); + left: max(16px, calc(16px + env(safe-area-inset-left))); + right: max(16px, calc(16px + env(safe-area-inset-right))); + /* centré horizontalement */ + width: auto; + border-radius: 20px; + padding: 16px 18px 18px; + gap: 10px; + z-index: 20; + box-shadow: 5px 5px 0px #333; + /* Caché par défaut */ + opacity: 0; + pointer-events: none; + transform: translateY(12px); + transition: opacity .2s ease, transform .2s ease; + } + + .legend--open { + opacity: 1; + pointer-events: auto; + transform: translateY(0); + } + + /* Croix visible sur mobile */ + .legend__close { + display: flex; + align-items: center; + justify-content: center; + background: none; + border: 2px solid #333; + border-radius: 6px; + width: 24px; + height: 24px; + font-size: 12px; + font-weight: bold; + cursor: pointer; + color: #333; + box-shadow: 1px 1px 0 #333; + } + + .legend__title { + font-size: 15px; + } + + .legend__item { + font-size: 14px; + gap: 10px; + } + + .legend__swatch { + width: 20px; + height: 13px; + } + + .legend__dot { + width: 14px; + height: 14px; + } } diff --git a/frontend/src/components/Legend/Legend.jsx b/frontend/src/components/Legend/Legend.jsx index 145798c..6af370a 100644 --- a/frontend/src/components/Legend/Legend.jsx +++ b/frontend/src/components/Legend/Legend.jsx @@ -1,9 +1,9 @@ +import { useState } from 'react'; import './Legend.css'; -export default function Legend() { +function LegendContent() { return ( - + + ); +} + +export default function Legend() { + const [open, setOpen] = useState(false); + + return ( + <> + {/* Bouton visible uniquement sur mobile */} + + + {/* Backdrop mobile quand ouvert */} + {open && ( +
setOpen(false)} aria-hidden="true" /> + )} + + + ); }