Components / AI Chat Interfaces

AI Chat Sidebar

A conversation history sidebar listing previous AI chat sessions with search, date grouping, and active state indicators.

Live Preview — ai-chat-sidebar-01
2026-02-19
2026-02-18
2026-02-17

Installation

Dependencies

Install the core libraries required for this component.

npm
npm install react

Shadcn UI Setup

Add the necessary Shadcn UI primitives.

npm
npx shadcn-ui@latest add card input button badge separator

Source Code

ai-chat-sidebar-01.tsx
import { useState } from "react";
import { Card, CardContent } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Separator } from "@/components/ui/separator";

interface Conversation {
    id: number;
    title: string;
    lastMessage: string;
    date: string; // YYYY-MM-DD
    unread: boolean;
}

export default function AIChatSidebar01() {
    const [search, setSearch] = useState("");
    const [activeConversation, setActiveConversation] = useState<number | null>(1);

    // Self-contained conversation data
    const conversations: Conversation[] = [
        {
            id: 1,
            title: "ChatGPT - Daily Summary",
            lastMessage: "Here’s the summary of today’s tech news.",
            date: "2026-02-19",
            unread: false,
        },
        {
            id: 2,
            title: "GPT-4 - Project Planning",
            lastMessage: "We should break the tasks into milestones.",
            date: "2026-02-18",
            unread: true,
        },
        {
            id: 3,
            title: "Custom LLM - Experiment",
            lastMessage: "Testing new streaming AI responses.",
            date: "2026-02-17",
            unread: false,
        },
        {
            id: 4,
            title: "Custom LLM 2 - Preview",
            lastMessage: "Testing new version of AI responses.",
            date: "2026-02-19",
            unread: false,
        },
    ];

    // Group conversations by date
    const groupedConversations: Record<string, Conversation[]> = conversations.reduce(
        (acc, conv) => {
            if (!acc[conv.date]) acc[conv.date] = [];
            acc[conv.date].push(conv);
            return acc;
        },
        {} as Record<string, Conversation[]>
    );

    // Filtered by search
    const filteredGroupedConversations = Object.fromEntries(
        Object.entries(groupedConversations).map(([date, convs]) => [
            date,
            convs.filter((c) => c.title.toLowerCase().includes(search.toLowerCase())),
        ])
    );

    return (
        <Card className="w-[280px] p-2 flex flex-col h-full">
            {/* Search bar */}
            <CardContent className="p-0">
                <Input
                    placeholder="Search conversations..."
                    value={search}
                    onChange={(e) => setSearch(e.target.value)}
                />
            </CardContent>

            {/* Conversations list */}
            <CardContent className="flex-1 overflow-y-auto p-2 pt-0! space-y-3">
                {Object.entries(filteredGroupedConversations).map(([date, convs]) =>
                    convs.length > 0 ? (
                        <div key={date} className="space-y-3">
                            <div className="text-xs text-muted-foreground font-semibold">{date}</div>
                            <div className="flex flex-col gap-1">
                                {convs.map((conv) => (
                                    <Button
                                        key={conv.id}
                                        variant={activeConversation === conv.id ? "default" : "ghost"}
                                        className="w-full justify-between items-center px-2 h-10 py-2"
                                        onClick={() => setActiveConversation(conv.id)}
                                    >
                                        <div className="flex flex-col text-left overflow-hidden">
                                            <span className="text-xs font-medium truncate">{conv.title}</span>
                                            <span className="text-[10px] opacity-60 truncate">
                                                {conv.lastMessage}
                                            </span>
                                        </div>
                                        {conv.unread && (
                                            <Badge variant="secondary" className="flex-shrink-0 ml-2">
                                                New
                                            </Badge>
                                        )}
                                    </Button>
                                ))}
                            </div>
                        </div>
                    ) : null
                )}
            </CardContent>

            <Separator className="mt-12" />

            {/* Footer actions */}
            <CardContent className="p-2 flex flex-col gap-2">
                <Button size="sm" className="w-full">
                    + New Conversation
                </Button>
                <Button size="sm" className="w-full">
                    Export Conversations
                </Button>
            </CardContent>
        </Card>
    );
}

Shadcn Components

Primitives required in your @/components/ui directory.

Component Path
card @/components/ui/card
input @/components/ui/input
button @/components/ui/button
badge @/components/ui/badge
separator @/components/ui/separator

Type Reference

Types and interfaces defined in this component.

Conversation
interface Conversation {
    id: number;
    title: string;
    lastMessage: string;
    date: string; // YYYY-MM-DD
    unread: boolean;
}

Functional Logic

Internal functions used to handle component logic.

Function Parameters
AIChatSidebar01() None

State Management

React state variables managed within this component.

Variable Initial Value
search ""

Variables

All variable declarations found in this component.

Name Kind Value
filteredGroupedConversations const Object.fromEntries(

JSX Tags Usage

Every JSX/HTML tag used in this component, with usage count and source.

Tag Count Type Source
<Badge> Library @/components/ui/badge
<Card> Library @/components/ui/card
<CardContent> Library @/components/ui/card
<Separator> Library @/components/ui/separator
<Button> Native Native HTML
<div> Native Native HTML
<Input> Native Native HTML
<number> Native Native HTML
<span> Native Native HTML
<string> Native Native HTML

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 Chat Window — A full-featured AI chat window with message history, streaming response animation, and conversation management.
  • AI Streaming Text — A typewriter-style streaming text component that simulates token-by-token AI response generation with cursor animation.
  • 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.