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
+11 -1
View File
@@ -99,6 +99,8 @@
<!-- Erreur -->
<div v-if="errorMsg" class="error-bubble">{{ errorMsg }}</div>
<ChatNewConversation v-if="hasHistory && !loading" @reset="nouvelleConversation" />
</div>
<!-- Input -->
@@ -169,7 +171,10 @@ const props = withDefaults(defineProps<{
rendreMarkdown?: boolean
/** Message affiché quand la limite quotidienne (429) est atteinte */
messageLimite?: string
/** Clé de persistance (sessionStorage). Même clé = même conversation (ex. mobile + desktop) */
chatKey?: string
}>(), {
chatKey: 'accueil',
endpoint: '/api/chatbot',
titre: 'Chatbot AEP',
placeholderReplie: 'Pose une question sur le réseau…',
@@ -188,7 +193,7 @@ const emit = defineEmits<{
}>()
const isExpanded = ref(false)
const messages = ref<ChatMessage[]>([])
const { messages, hasHistory, clear } = useChatSession<ChatMessage>(() => props.chatKey)
const inputText = ref('')
const loading = ref(false)
const errorMsg = ref('')
@@ -225,6 +230,11 @@ function detectHashtagsFromQuery(query: string): string[] {
return detected.slice(0, 3)
}
function nouvelleConversation() {
clear()
errorMsg.value = ''
}
function toggleExpand() {
isExpanded.value = !isExpanded.value
}