fix(aep-v1.1): bugs E2E M1 M2 M3 L1 L2 L3

M1 - Chips a11y : converti les <span> chips mobile (criteres, types,
echelle, fonctions) en <button type=button> avec aria-pressed pour
support clavier et lecteurs d'ecran (sidebar desktop deja en boutons).

M2 - Effacer les filtres ne vide pas la search : resetFilters() reset
maintenant aussi mobileSearch dans pratiques-regeneratives.vue et
index.vue.

M3 - FAB Soutenir overlap chip Agence : repositionne le FAB Soutenir
en stack vertical avec le FAB Chatbot (right: 16px, bottom: 84px) au
lieu de left: 16px, bottom: 68px. Evite l'overlap avec les chips de
la bottom-sheet sur viewport intermediaire.

L1 - /fiche/[id] introuvable pour pratiques : ajoute un fallback dans
pages/fiche/[id].vue qui detecte si l'id correspond a une pratique
regenerative et redirige vers /pratique/[id] (navigateTo replace).

L2 - Label retour incorrect sur /proposer-pratique : harmonise en
'Retour aux pratiques regeneratives'.

L3 - Map ne fitBounds pas apres filtre : EuropeMap et NavMap appellent
maintenant fitBounds(bounds, padding 40px, maxZoom 10) quand la liste
filtree contient 1 a 15 markers. Saute le tout premier rendu pour
preserver la vue initiale.
This commit is contained in:
Jules Neny
2026-04-30 02:31:31 +02:00
parent 914759a815
commit 682d5d337e
7 changed files with 88 additions and 11 deletions

View File

@@ -72,6 +72,21 @@ const { data: org, pending, error } = await useFetch<Org>(`/api/fiche/${orgId}`,
key: `fiche-${orgId}`,
})
// ── Fallback Pratiques regeneratives (bug E2E L1) ─────────────────────
// Si /api/fiche/:id echoue, on regarde si l'id correspond a une pratique
// regenerative et on redirige automatiquement vers /pratique/:id.
if (error.value) {
try {
const pratiquesRes = await $fetch<{ list: { id: number }[] }>('/api/pratiques')
const numericId = Number(orgId)
if (!isNaN(numericId) && pratiquesRes.list?.some((p) => p.id === numericId)) {
await navigateTo(`/pratique/${numericId}`, { replace: true })
}
} catch {
// pas de fallback dispo, on garde l'erreur
}
}
// ── Commentaires — tick de rafraîchissement ───────────────────────────
const commentRefreshTick = ref(0)

View File

@@ -205,15 +205,17 @@
<div class="mt-2">
<span class="text-xs font-bold uppercase tracking-wide block mb-1" style="color: var(--nav-text-muted);">ÉCHELLE</span>
<div class="flex flex-wrap gap-1">
<span
<button
v-for="opt in ECHELLES"
:key="opt"
type="button"
class="cursor-pointer px-2 py-0.5 rounded-full text-xs transition-all"
:style="echelle.includes(opt)
? 'background: var(--nav-primary); color: var(--nav-text-on-primary); font-weight: 600;'
: 'background: var(--nav-bg-alt); color: var(--nav-text-muted);'"
:aria-pressed="echelle.includes(opt)"
@click="toggleEchelle(opt)"
>{{ opt }}</span>
>{{ opt }}</button>
</div>
</div>
@@ -221,15 +223,17 @@
<div class="mt-2">
<span class="text-xs font-bold uppercase tracking-wide block mb-1" style="color: var(--nav-text-muted);">FONCTION</span>
<div class="flex flex-wrap gap-1">
<span
<button
v-for="fn in FONCTIONS"
:key="fn"
type="button"
class="cursor-pointer px-2 py-0.5 rounded-full text-xs transition-all"
:style="fonctions.includes(fn)
? 'background: var(--nav-primary); color: var(--nav-text-on-primary); font-weight: 600;'
: 'background: var(--nav-bg-alt); color: var(--nav-text-muted);'"
:aria-pressed="fonctions.includes(fn)"
@click="toggleFonction(fn)"
>{{ fn }}</span>
>{{ fn }}</button>
</div>
</div>
@@ -446,6 +450,7 @@ const hasActiveFilters = computed(() =>
function resetFilters() {
search.value = ''
mobileSearch.value = ''
echelle.value = []
fonctions.value = []
territoire.value = null

View File

@@ -211,15 +211,17 @@ le réemploi de matériaux en Belgique."</p>
<div class="mt-2">
<span class="text-xs font-bold uppercase tracking-wide block mb-1" style="color: var(--nav-text-muted);">CRITÈRES</span>
<div class="flex flex-wrap gap-1">
<span
<button
v-for="c in CRITERES"
:key="c.id"
type="button"
class="cursor-pointer px-2 py-0.5 rounded-full text-xs transition-all"
:style="criteres.includes(c.id)
? 'background: var(--nav-primary); color: var(--nav-text-on-primary); font-weight: 600;'
: 'background: var(--nav-bg-alt); color: var(--nav-text-muted);'"
:aria-pressed="criteres.includes(c.id)"
@click="toggleCritere(c.id)"
>{{ c.label }}</span>
>{{ c.label }}</button>
</div>
</div>
@@ -227,15 +229,17 @@ le réemploi de matériaux en Belgique."</p>
<div class="mt-2">
<span class="text-xs font-bold uppercase tracking-wide block mb-1" style="color: var(--nav-text-muted);">TYPE</span>
<div class="flex flex-wrap gap-1">
<span
<button
v-for="t in TYPES_ENTITE"
:key="t"
type="button"
class="cursor-pointer px-2 py-0.5 rounded-full text-xs transition-all"
:style="typesEntite.includes(t)
? 'background: var(--nav-primary); color: var(--nav-text-on-primary); font-weight: 600;'
: 'background: var(--nav-bg-alt); color: var(--nav-text-muted);'"
:aria-pressed="typesEntite.includes(t)"
@click="toggleType(t)"
>{{ TYPES_ENTITE_LABELS[t] ?? t }}</span>
>{{ TYPES_ENTITE_LABELS[t] ?? t }}</button>
</div>
</div>
@@ -457,6 +461,7 @@ const hasActiveFilters = computed(() =>
function resetFilters() {
search.value = ''
mobileSearch.value = ''
criteres.value = []
typesEntite.value = []
pays.value = []

View File

@@ -3,7 +3,7 @@
<div class="contribuer-inner">
<!-- Retour -->
<NuxtLink to="/pratiques-regeneratives" class="back-link">
Retour à la carte
Retour aux pratiques régénératives
</NuxtLink>
<!-- En-tête -->