feat(chatbot): persistance des conversations en sessionStorage + bouton Nouvelle conversation

- composables/useChatSession.ts : historique réactif partagé (useState) et persisté sous aep-chat-<clé>, version de schéma {v:1}, 40 derniers messages, restauration au mount uniquement (SSR-safe), try/catch partout, messages transient jamais écrits
- clés : accueil (Placeholder + Sheet), agences (Placeholder réseaux + ChatbotReseaux), taff, pensees (suffixée par l'auteur)
- ChatbotPlaceholder reçoit sa clé par prop chatKey (défaut accueil)
- ChatNewConversation : bouton sobre, visible seulement s'il y a un historique

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015vcVGz8i4WpZm2dixKUiSD
This commit is contained in:
Jules Neny
2026-10-09 03:38:15 +02:00
co-authored by Claude Opus 5.5
parent 31edbd37af
commit 75d8440601
8 changed files with 174 additions and 19 deletions
+6 -2
View File
@@ -275,6 +275,8 @@
<div v-if="chatLoading" class="taff-msg taff-msg--bot">
<span class="taff-typing"><span/><span/><span/></span>
</div>
<ChatNewConversation v-if="chatHasHistory && !chatLoading" @reset="clearChat" />
</div>
<!-- Input -->
@@ -581,6 +583,8 @@ interface ChatMessage {
role: 'user' | 'bot'
content: string
recommandations?: { id: string; nom: string; raison: string }[]
/** Message d'erreur : affiché mais jamais persisté */
transient?: boolean
}
const { render: renderMd } = useMarkdown()
@@ -588,7 +592,7 @@ const { render: renderMd } = useMarkdown()
const chatOpen = ref(false)
const chatInput = ref('')
const chatLoading = ref(false)
const chatMessages = ref<ChatMessage[]>([])
const { messages: chatMessages, hasHistory: chatHasHistory, clear: clearChat } = useChatSession<ChatMessage>('taff')
const chatMessagesEl = ref<HTMLElement | null>(null)
async function sendChat() {
@@ -610,7 +614,7 @@ async function sendChat() {
recommandations: res.plateformes_recommandees ?? [],
})
} catch (e: any) {
chatMessages.value.push({ role: 'bot', content: e?.data?.statusMessage ?? 'Erreur — réessaie dans un instant.' })
chatMessages.value.push({ role: 'bot', content: e?.data?.statusMessage ?? 'Erreur — réessaie dans un instant.', transient: true })
} finally {
chatLoading.value = false
await nextTick()