feat: F024 global AI assistant — contextual decision intelligence drawer

Wires the existing "AI Assistent" button in the TopBar and adds a 420px
slide-in drawer with context-aware suggestions, message thread, loading
animation, and action cards requiring manual confirmation. Template-based
mock service returns German-language answers keyed by route + question
keywords — no real LLM calls, no invented facts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Benjamin Sutter
2026-05-17 13:27:33 +02:00
parent 71f4b1eeb6
commit 30e840489d
13 changed files with 1222 additions and 0 deletions
+36
View File
@@ -0,0 +1,36 @@
import { create } from 'zustand'
import type { AssistantContext, AssistantMessage } from '../domain/assistant'
interface AssistantState {
isOpen: boolean
context: AssistantContext | null
messages: AssistantMessage[]
isLoading: boolean
error: string | null
open: () => void
close: () => void
setContext: (ctx: AssistantContext) => void
updateContext: (partial: Partial<AssistantContext>) => void
addMessage: (msg: AssistantMessage) => void
setLoading: (v: boolean) => void
setError: (e: string | null) => void
clearConversation: () => void
}
export const useAssistantStore = create<AssistantState>((set) => ({
isOpen: false,
context: null,
messages: [],
isLoading: false,
error: null,
open: () => set({ isOpen: true }),
close: () => set({ isOpen: false }),
setContext: (ctx) => set({ context: ctx }),
updateContext: (partial) => set((s) => ({ context: s.context ? { ...s.context, ...partial } : null })),
addMessage: (msg) => set((s) => ({ messages: [...s.messages, msg] })),
setLoading: (v) => set({ isLoading: v }),
setError: (e) => set({ error: e }),
clearConversation: () => set({ messages: [], error: null }),
}))