| import { useEffect, useRef } from "react"; |
| import { motion } from "motion/react"; |
| import { Bot } from "lucide-react"; |
| import type { Message } from "./types"; |
| import MessageBubble from "./MessageBubble"; |
| const maintivalogo = "/maintiva-logo.png"; |
|
|
| const WELCOME_FEATURES = [ |
| { emoji: "π", title: "Data Analysis", desc: "Get actionable insights and root cause" }, |
| { emoji: "π§ ", title: "Knowledge Based", desc: "Handbook, SOP, Documents, or Databases" }, |
| { emoji: "π€", title: "Voice Mode", desc: "Ask questions using your voice" }, |
| { emoji: "π¬", title: "Natural language", desc: "Natural interaction" }, |
| ]; |
|
|
| interface ChatWindowProps { |
| messages: Message[]; |
| isLoading: boolean; |
| streamingMsgId: string | null; |
| userName?: string; |
| } |
|
|
| export default function ChatWindow({ messages, isLoading, streamingMsgId, userName }: ChatWindowProps) { |
| const firstName = userName?.split(" ")[0] ?? ""; |
| const bottomRef = useRef<HTMLDivElement>(null); |
|
|
| useEffect(() => { |
| bottomRef.current?.scrollIntoView({ behavior: "smooth" }); |
| }, [messages, isLoading]); |
|
|
| if (messages.length === 0 && !isLoading) { |
| return ( |
| <div className="flex-1 overflow-y-auto flex flex-col items-center justify-center gap-6 px-4 sm:px-6 xl:px-8 pb-4"> |
| <motion.div |
| className="flex flex-col items-center gap-4 xl:gap-6 w-full max-w-sm sm:max-w-md xl:max-w-2xl" |
| initial={{ opacity: 0, scale: 0.9 }} |
| animate={{ opacity: 1, scale: 1 }} |
| transition={{ duration: 0.5, ease: "easeOut" }} |
| > |
| <div className="w-20 h-20 xl:w-28 xl:h-28 rounded-3xl bg-gradient-to-br from-brand-green-light to-brand-green shadow-xl shadow-brand-green/25 flex items-center justify-center"> |
| <Bot className="h-10 w-10 xl:h-14 xl:w-14 text-white" /> |
| </div> |
| |
| <div className="text-center"> |
| <h2 className="text-2xl xl:text-4xl font-bold text-neutral-900"> |
| {firstName ? `Hi, ${firstName}! π` : "Hello! π"} |
| </h2> |
| <p className="mt-2 text-neutral-500 text-sm xl:text-base leading-relaxed"> |
| Welcome to{" "} |
| <span className="inline-flex items-center gap-1 font-bold text-neutral-800 align-middle"> |
| <img src={maintivalogo} alt="Maintiva" className="h-4 w-4 xl:h-5 xl:w-5 rounded-sm object-contain" /> |
| Maintiva Agent |
| </span>{" "} |
| Turn your data into fast, intelligent decisions. Instantly uncover root causes, spot hidden patterns, and resolve issues before they escalate. |
| </p> |
| </div> |
| |
| <div className="grid grid-cols-2 xl:grid-cols-4 gap-3 xl:gap-4 w-full mt-2"> |
| {WELCOME_FEATURES.map((f) => ( |
| <div |
| key={f.title} |
| className="flex flex-col gap-1 xl:gap-2 p-3 xl:p-4 rounded-xl bg-white border border-neutral-100 shadow-sm text-left" |
| > |
| <span className="text-xl xl:text-3xl">{f.emoji}</span> |
| <span className="text-sm xl:text-base font-semibold text-neutral-800">{f.title}</span> |
| <span className="text-xs xl:text-sm text-neutral-400">{f.desc}</span> |
| </div> |
| ))} |
| </div> |
| </motion.div> |
| </div> |
| ); |
| } |
|
|
| return ( |
| <div className="flex-1 overflow-y-auto py-4 space-y-1"> |
| {/* Constrain message width on large/seminar screens */} |
| <div className="w-full max-w-4xl xl:max-w-5xl mx-auto"> |
| {messages.map((message) => ( |
| <MessageBubble |
| key={message.id} |
| message={message} |
| isStreamingPlaceholder={streamingMsgId === message.id} |
| /> |
| ))} |
| <div ref={bottomRef} /> |
| </div> |
| </div> |
| ); |
| } |
|
|