"use client" import { AnimatePresence, motion } from "motion/react" import { useEffect, useRef, useState } from "react" import { ArrowUpIcon, MessageCircleIcon, XIcon } from "lucide-react" import { cn } from "@/lib/utils" import { brandName } from "../../lib/content" import type { TemplateContent } from "../../lib/types" import { useAiAccess } from "../access-context" import { BookingCard } from "./booking-card" import { useAiChat } from "./use-ai-chat" const ease = [0.22, 1, 0.36, 1] as const const QUICK_REPLIES = ["Wie sind Ihre Öffnungszeiten?", "Ich möchte einen Termin vereinbaren", "Was bieten Sie an?"] // Chat-Assistent unten rechts; nutzt Palette und Schriften der Vorlage (bg-t-*, font-t-*) export function ChatWidget({ content }: { content: TemplateContent }) { const access = useAiAccess() const chat = useAiChat({ access, mode: "chat" }) const [open, setOpen] = useState(false) const [teaser, setTeaser] = useState(false) const [draft, setDraft] = useState("") const listRef = useRef(null) const enabled = Boolean(access && content.ai.chat) const name = content.ai.name.trim() || "Assistent" const brand = brandName(content) const greeting = content.ai.greeting.trim() || `Hallo! Ich bin ${name}${brand ? ` von ${brand}` : ""}. Wie kann ich Ihnen helfen?` useEffect(() => { if (!enabled) return const timer = setTimeout(() => setTeaser(true), 4000) return () => clearTimeout(timer) }, [enabled]) useEffect(() => { listRef.current?.scrollTo({ top: listRef.current.scrollHeight, behavior: "smooth" }) }, [chat.messages, open]) if (!enabled) return null const last = chat.messages[chat.messages.length - 1] const typing = chat.pending && last?.role === "assistant" && last.parts.length === 0 function submit(text: string) { if (!text.trim() || chat.pending) return setDraft("") void chat.send(text) } return (
{open && (
{name.charAt(0).toUpperCase()}

{name}

KI-Assistent · antwortet sofort

{greeting} {chat.messages.map((message, i) => (
{message.parts.map((part, j) => part.type === "booking" ? ( ) : ( {part.text} ) )}
))} {typing && (
{[0, 1, 2].map((dot) => ( ))}
)} {chat.error &&

{chat.error}

} {chat.messages.length === 0 && (
{QUICK_REPLIES.map((reply) => ( ))}
)}
{ event.preventDefault() submit(draft) }} > setDraft(event.target.value)} placeholder="Nachricht schreiben …" aria-label="Nachricht" maxLength={1500} className="min-w-0 flex-1 rounded-full bg-t-surface px-4 py-2.5 text-sm outline-none placeholder:text-t-muted focus:ring-2 focus:ring-t-accent/40" />

KI-Demo · Antworten können Fehler enthalten

)}
{teaser && !open && ( setOpen(true)} className="max-w-60 cursor-pointer rounded-2xl rounded-br-md bg-t-bg px-4 py-3 text-left text-sm text-t-fg shadow-xl ring-1 ring-t-fg/10" > Fragen? Ich antworte sofort – auch auf Terminwünsche. )} { setOpen(!open) setTeaser(false) }} whileHover={{ scale: 1.06 }} whileTap={{ scale: 0.94 }} className="grid size-14 cursor-pointer place-items-center rounded-full bg-t-accent text-t-accent-fg shadow-[0_12px_40px_-8px_var(--t-accent)]" > {open ? : }
) } function Bubble({ role, children }: { role: "user" | "assistant"; children: string }) { return (

{children}

) }