Components / AI Chat Interfaces

AI Chat Window

A full-featured AI chat window with message history, streaming response animation, and conversation management.

tsx
"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>
  );
}

Installation

Dependencies

  • react
  • lucide-react
                            npm install react lucide-react
                        

Related Components

  • AI Chat Bubble — A conversational chat bubble component with typing indicator, avatar support, and message timestamps for AI chat interfaces.
  • AI Chat Input Bar — A modern chat input bar with send button, attachment support, and auto-resize textarea for AI conversation interfaces.
  • AI Streaming Text — A typewriter-style streaming text component that simulates token-by-token AI response generation with cursor animation.
  • AI Chat Sidebar — A conversation history sidebar listing previous AI chat sessions with search, date grouping, and active state indicators.
  • AI Model Selector — A dropdown model selector for choosing between AI models (GPT-4, Claude, Gemini) with model info badges and capability indicators.
  • AI Response Actions — An action bar for AI responses with copy, regenerate, thumbs up/down, and share buttons with tooltip labels.