first implementation

This commit is contained in:
Adrien
2026-03-31 20:58:47 +02:00
parent dc0bcab36e
commit 618e28b354
1878 changed files with 1381732 additions and 5 deletions
+122
View File
@@ -0,0 +1,122 @@
import { defineStore } from 'pinia'
import { ref } from 'vue'
import { api } from '@/services/api'
export interface ChatMessage {
id: string
role: 'USER' | 'ASSISTANT'
content: string
sources: Array<{ bookTitle: string; page: number | null }>
createdAt: string
}
export interface ChatSession {
sessionId: string
topicId: string | null
createdAt: string
}
export const useChatStore = defineStore('chat', () => {
const session = ref<ChatSession | null>(null)
const messages = ref<ChatMessage[]>([])
const loading = ref(false)
const sending = ref(false)
const error = ref<string | null>(null)
async function createSession(topicId?: string): Promise<boolean> {
loading.value = true
error.value = null
try {
const body = topicId ? { topicId } : {}
const response = await api.post<ChatSession>('/chat/sessions', body)
session.value = response.data
messages.value = []
return true
} catch (err: any) {
error.value = err.message
return false
} finally {
loading.value = false
}
}
async function loadMessages(): Promise<void> {
if (!session.value) return
loading.value = true
error.value = null
try {
const response = await api.get<ChatMessage[]>(
`/chat/sessions/${session.value.sessionId}/messages`
)
messages.value = response.data
} catch (err: any) {
error.value = err.message
} finally {
loading.value = false
}
}
async function sendMessage(content: string): Promise<boolean> {
if (!session.value) return false
sending.value = true
error.value = null
// Optimistically add user message
const tempUserMsg: ChatMessage = {
id: crypto.randomUUID(),
role: 'USER',
content,
sources: [],
createdAt: new Date().toISOString()
}
messages.value.push(tempUserMsg)
try {
const response = await api.post<ChatMessage>(
`/chat/sessions/${session.value.sessionId}/messages`,
{ content }
)
// Replace temp message & add assistant response
messages.value = messages.value.filter((m) => m.id !== tempUserMsg.id)
// Reload full conversation to stay in sync
await loadMessages()
return true
} catch (err: any) {
// Remove optimistic message on failure
messages.value = messages.value.filter((m) => m.id !== tempUserMsg.id)
error.value = err.message
return false
} finally {
sending.value = false
}
}
async function deleteSession(): Promise<boolean> {
if (!session.value) return false
loading.value = true
error.value = null
try {
await api.delete(`/chat/sessions/${session.value.sessionId}`)
session.value = null
messages.value = []
return true
} catch (err: any) {
error.value = err.message
return false
} finally {
loading.value = false
}
}
return {
session,
messages,
loading,
sending,
error,
createSession,
loadMessages,
sendMessage,
deleteSession
}
})