feat(aep-v1.1): PA5 chatbot pratiques regeneratives
- Nouveau endpoint server/api/chatbot-pratiques.post.ts qui interroge le JSON statique pratiques-regeneratives.json (52 fiches V1) avec Mistral Small. Prompt systeme adapte aux 8 criteres rege et types d'entites. Rate limit 10/jour, circuit breaker partage. - ChatbotPlaceholder + ChatbotSheet rendus generiques via props (endpoint, title, placeholder, ficheBasePath) + slot onboarding. La carte ecosysteme AEP continue d'utiliser /api/chatbot, la carte pratiques rege utilise /api/chatbot-pratiques. - pratiques-regeneratives.vue : ChatbotPlaceholder integre sous la carte Europe desktop (replie par defaut), FAB mobile + ChatbotSheet bottom sheet, handler highlightOrgs pour surligner la fiche reco.
This commit is contained in:
@@ -75,6 +75,27 @@
|
||||
</template>
|
||||
</ClientOnly>
|
||||
</div>
|
||||
<ChatbotPlaceholder
|
||||
endpoint="/api/chatbot-pratiques"
|
||||
title="Chatbot Pratiques régé"
|
||||
placeholder="Pose une question sur les pratiques régénératives…"
|
||||
ficheBasePath="/pratique"
|
||||
@highlightOrgs="onHighlightOrgs"
|
||||
>
|
||||
<template #onboarding>
|
||||
<p>Ce chatbot interroge la base des pratiques régénératives
|
||||
(Mistral FR, serveur européen souverain, zéro rétention).</p>
|
||||
<p>Pour t'aider à trouver les pratiques pertinentes,
|
||||
formule ta requête ainsi :</p>
|
||||
<ul>
|
||||
<li>• Besoin : [matériaux biosourcés / réemploi / posture politique...]</li>
|
||||
<li>• Type : [agence / coopérative / collectif / réseau...]</li>
|
||||
<li>• Lieu : [pays ou région]</li>
|
||||
</ul>
|
||||
<p class="example">Exemple : "Je cherche une coopérative qui travaille
|
||||
le réemploi de matériaux en Belgique."</p>
|
||||
</template>
|
||||
</ChatbotPlaceholder>
|
||||
</div>
|
||||
|
||||
<!-- Carte Outre-mer (pleine hauteur, scroll) -->
|
||||
@@ -278,22 +299,21 @@
|
||||
|
||||
</main>
|
||||
|
||||
<!-- ═══════════════════════════════════════ BOUTON CHATBOT FLOTTANT (mobile) — désactivé V1 -->
|
||||
<!-- ═══════════════════════════════════════ BOUTON CHATBOT FLOTTANT (mobile) -->
|
||||
<button
|
||||
v-if="false"
|
||||
class="lg:hidden fixed bottom-6 right-4 z-[1000] flex items-center gap-2 px-4 rounded-full shadow-lg"
|
||||
style="
|
||||
height: 48px;
|
||||
background: var(--nav-primary);
|
||||
opacity: 0.5;
|
||||
opacity: 0.92;
|
||||
color: var(--nav-text-on-primary);
|
||||
box-shadow: 0 4px 16px rgba(26,34,56,0.25);
|
||||
font-family: var(--nav-font);
|
||||
font-size: 0.875rem;
|
||||
font-weight: 600;
|
||||
"
|
||||
aria-label="Chatbot (bientôt disponible)"
|
||||
disabled
|
||||
aria-label="Ouvrir l'assistant Chatbot"
|
||||
@click="chatbotOpen = true"
|
||||
>
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>
|
||||
@@ -301,6 +321,30 @@
|
||||
<span>Chatbot</span>
|
||||
</button>
|
||||
|
||||
<!-- ═══════════════════════════════════════ CHATBOT BOTTOM SHEET (mobile) -->
|
||||
<ChatbotSheet
|
||||
:modelValue="chatbotOpen"
|
||||
endpoint="/api/chatbot-pratiques"
|
||||
title="Chatbot Pratiques régé"
|
||||
ficheBasePath="/pratique"
|
||||
@update:modelValue="chatbotOpen = $event"
|
||||
@highlightOrgs="onHighlightOrgs"
|
||||
>
|
||||
<template #onboarding>
|
||||
<p>Ce chatbot interroge la base des pratiques régénératives
|
||||
(Mistral FR, serveur européen souverain, zéro rétention).</p>
|
||||
<p>Pour t'aider à trouver les pratiques pertinentes,
|
||||
formule ta requête ainsi :</p>
|
||||
<ul>
|
||||
<li>• Besoin : [matériaux biosourcés / réemploi / posture politique...]</li>
|
||||
<li>• Type : [agence / coopérative / collectif / réseau...]</li>
|
||||
<li>• Lieu : [pays ou région]</li>
|
||||
</ul>
|
||||
<p class="example">Exemple : "Je cherche une coopérative qui travaille
|
||||
le réemploi de matériaux en Belgique."</p>
|
||||
</template>
|
||||
</ChatbotSheet>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -332,6 +376,27 @@ const pays = ref<string[]>(
|
||||
const selectedId = ref<number | null>(null)
|
||||
const mobileMapView = ref<'europe' | 'outremer'>('europe')
|
||||
const desktopMapView = ref<'europe' | 'outremer'>('europe')
|
||||
const chatbotOpen = ref(false)
|
||||
|
||||
// Surlignage temporaire (5 sec) suite a une reponse chatbot
|
||||
let highlightTimer: ReturnType<typeof setTimeout> | null = null
|
||||
const prevSelectedId = ref<number | null>(null)
|
||||
|
||||
function onHighlightOrgs(ids: (number | string)[]) {
|
||||
if (!ids.length) return
|
||||
const firstId = typeof ids[0] === 'string' ? parseInt(ids[0], 10) : ids[0]
|
||||
if (isNaN(firstId)) return
|
||||
|
||||
prevSelectedId.value = selectedId.value
|
||||
selectedId.value = firstId
|
||||
|
||||
if (highlightTimer) clearTimeout(highlightTimer)
|
||||
highlightTimer = setTimeout(() => {
|
||||
selectedId.value = prevSelectedId.value
|
||||
prevSelectedId.value = null
|
||||
highlightTimer = null
|
||||
}, 5000)
|
||||
}
|
||||
|
||||
// Refs vers les instances EuropeMap
|
||||
const europeMapRef = ref<any>(null)
|
||||
|
||||
Reference in New Issue
Block a user