Displays conversation history and allows management (new, select, rename, delete).
Overview
The ChatSidebar component provides:
- Conversation list with real-time updates
- New conversation button
- Conversation selection
- Rename conversation functionality
- Delete conversation functionality
- Subscription status display (integrated)
Basic Usage
import ChatSidebar from "@/components/ai/ChatSidebar";
export default function ChatPage() {
const [currentConversationId, setCurrentConversationId] = useState<string | null>(null);
return (
<div className="flex h-screen">
<ChatSidebar
currentConversationId={currentConversationId}
onSelectConversation={(id) => setCurrentConversationId(id)}
onNewConversation={() => {
// Create new conversation logic
setCurrentConversationId(null);
}}
/>
{/* Main chat interface */}
</div>
);
}
Props
interface ChatSidebarProps {
currentConversationId: string | null;
onSelectConversation: (conversationId: string) => void;
onNewConversation: () => void;
}
Features
Real-time Updates
The component automatically syncs with Firestore:
// Uses Firestore onSnapshot for real-time updates
const q = query(
collection(db, "users", userId, "conversations"),
orderBy("updatedAt", "desc")
);
onSnapshot(q, (snapshot) => {
// Updates conversation list automatically
});
Conversation Management
- New Conversation - Creates a new conversation document
- Select Conversation - Loads conversation messages
- Rename Conversation - Updates conversation title
- Delete Conversation - Removes conversation and messages
Path-Based Security
Conversations are stored using path-based security:
users/{userId}/conversations/{conversationId}
This ensures users can only access their own conversations.
Integration Example
Full Chat Page Integration
"use client";
import { useState, useEffect } from "react";
import ChatSidebar from "@/components/ai/ChatSidebar";
import ChatInterface from "@/components/ai/ChatInterface";
import { getAuthInstance, getFirestoreInstance } from "@core/src/lib/firebase/client";
import { onAuthStateChanged } from "firebase/auth";
export default function ChatPage() {
const [user, setUser] = useState<any>(null);
const [currentConversationId, setCurrentConversationId] = useState<string | null>(null);
const [messages, setMessages] = useState([]);
useEffect(() => {
const auth = getAuthInstance();
const unsubscribe = onAuthStateChanged(auth, (firebaseUser) => {
setUser(firebaseUser);
});
return () => unsubscribe();
}, []);
const handleSelectConversation = (conversationId: string) => {
setCurrentConversationId(conversationId);
// Load messages for this conversation
};
const handleNewConversation = async () => {
// Create new conversation logic
const newId = await createNewConversation();
setCurrentConversationId(newId);
};
return (
<div className="flex h-screen">
<ChatSidebar
currentConversationId={currentConversationId}
onSelectConversation={handleSelectConversation}
onNewConversation={handleNewConversation}
/>
<div className="flex-1">
<ChatInterface messages={messages} />
</div>
</div>
);
}
Conversation Data Structure
Conversations are stored in Firestore with this structure:
interface Conversation {
id: string;
title: string;
createdAt: Timestamp;
updatedAt: Timestamp;
lastMessage?: string;
messageCount?: number;
}
Styling
The component uses DaisyUI classes:
bg-base-200- Sidebar backgroundborder-r border-base-content/10- Right borderbtn btn-primary- New chat buttonbadge- Active conversation indicator
Customization
Custom Styling
<ChatSidebar
className="w-80" // Custom width
currentConversationId={currentConversationId}
onSelectConversation={handleSelect}
onNewConversation={handleNew}
/>
Custom New Conversation Button
The component includes a "New Chat" button, but you can customize the behavior:
const handleNewConversation = async () => {
// Your custom logic
const newConversation = await createConversation({
title: "New Conversation",
userId: user.uid,
});
setCurrentConversationId(newConversation.id);
};
Error Handling
The component handles:
- Loading states (shows spinner while loading)
- Empty states (shows message when no conversations)
- Firestore errors (displays error message)
- Authentication errors (handles unauthenticated state)
Best Practices
- Real-time Updates - Component automatically syncs, no manual refresh needed
- Path-Based Security - Conversations are scoped to user via Firestore path
- Optimistic Updates - Update UI immediately, sync with Firestore
- Error Handling - Always handle Firestore errors gracefully
- Performance - Use Firestore indexes for efficient queries
Firestore Security Rules
Ensure your Firestore rules allow conversation access:
match /users/{userId}/conversations/{conversationId} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
Next Steps
- Learn about Chat Interface
- Explore Chat Message for individual messages
- Check out Subscription Status (integrated in sidebar)
- Review Firestore Setup for database configuration