Components / AI Chat Interfaces
AI Chat Window
A full-featured AI chat window with message history, streaming response animation, and conversation management.
Components / AI Chat Interfaces
A full-featured AI chat window with message history, streaming response animation, and conversation management.
"use client";
import React, { useState, useRef, useEffect } from "react";
import { Bot, User, Copy, RotateCcw, MoreHorizontal } from "lucide-react";
interface Message {
id: string;
role: "user" | "assistant";
content: string;
}
export default function AIChatWindow() {
const [messages, setMessages] = useState<Message[]>([
{ id: "1", role: "assistant", content: "Hello! I'm your AI assistant. How can I help you today?" },
]);
const [input, setInput] = useState("");
const bottomRef = useRef<HTMLDivElement>(null);
useEffect(() => {
bottomRef.current?.scrollIntoView({ behavior: "smooth" });
}, [messages]);
const handleSend = () => {
if (!input.trim()) return;
const userMsg: Message = { id: Date.now().toString(), role: "user", content: input.trim() };
setMessages((prev) => [...prev, userMsg]);
setInput("");
setTimeout(() => {
const aiMsg: Message = {
id: (Date.now() + 1).toString(),
role: "assistant",
content: "I understand your question. Let me help you with that. This is a simulated AI response for demonstration purposes.",
};
setMessages((prev) => [...prev, aiMsg]);
}, 1200);
};
return (
<div className="flex flex-col h-[500px] rounded-xl border border-zinc-200 dark:border-zinc-800 bg-white dark:bg-zinc-950 overflow-hidden">
<div className="flex items-center justify-between px-4 py-3 border-b border-zinc-200 dark:border-zinc-800">
<div className="flex items-center gap-2">
<div className="h-8 w-8 rounded-full bg-gradient-to-br from-violet-500 to-purple-600 flex items-center justify-center">
<Bot className="h-4 w-4 text-white" />
</div>
<div>
<p className="text-sm font-medium text-zinc-900 dark:text-zinc-100">AI Assistant</p>
<p className="text-xs text-green-500">● Online</p>
</div>
</div>
<button className="p-1.5 rounded-lg hover:bg-zinc-100 dark:hover:bg-zinc-800">
<MoreHorizontal className="h-4 w-4 text-zinc-500" />
</button>
</div>
<div className="flex-1 overflow-y-auto p-4 space-y-4">
{messages.map((msg) => (
<div key={msg.id} className={`flex gap-3 ${msg.role === "user" ? "flex-row-reverse" : ""}`}>
<div className={`h-7 w-7 rounded-full flex items-center justify-center shrink-0 ${
msg.role === "assistant"
? "bg-gradient-to-br from-violet-500 to-purple-600"
: "bg-zinc-200 dark:bg-zinc-700"
}`}>
{msg.role === "assistant" ? <Bot className="h-3.5 w-3.5 text-white" /> : <User className="h-3.5 w-3.5 text-zinc-600 dark:text-zinc-300" />}
</div>
<div className={`max-w-[70%] rounded-2xl px-4 py-2.5 text-sm ${
msg.role === "assistant"
? "bg-zinc-100 dark:bg-zinc-800 text-zinc-900 dark:text-zinc-100 rounded-tl-sm"
: "bg-blue-600 text-white rounded-tr-sm"
}`}>
{msg.content}
</div>
</div>
))}
<div ref={bottomRef} />
</div>
<div className="p-3 border-t border-zinc-200 dark:border-zinc-800">
<div className="flex items-center gap-2">
<input
value={input}
onChange={(e) => setInput(e.target.value)}
onKeyDown={(e) => e.key === "Enter" && handleSend()}
placeholder="Type a message..."
className="flex-1 rounded-xl border border-zinc-200 dark:border-zinc-700 bg-zinc-50 dark:bg-zinc-900 px-4 py-2.5 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500/20"
/>
<button
onClick={handleSend}
disabled={!input.trim()}
className="px-4 py-2.5 rounded-xl bg-blue-600 text-white text-sm font-medium hover:bg-blue-700 disabled:opacity-40 transition-colors"
>
Send
</button>
</div>
</div>
</div>
);
}react lucide-react npm install react lucide-react