DOCUMENTS_COMPONENT.md
Overview
The Documents component (DocumentSidebar) is a sidebar component that displays assigned documents for assistants with proper file type icons, image previews, and external link handling. It integrates with the sidebar UI system and provides document access for authenticated users.
Purpose
- Document Display: Show assigned documents in sidebar with file type icons
- Image Preview: Special handling for image documents with thumbnail previews
- External Links: Safe external document access with proper security attributes
- User State Management: Conditional rendering based on authentication status
Key Features
File Type Detection
- Icon Mapping: Automatic file type icons via DocumentHandler
- Image Handling: Special preview for image documents
- Fallback Support: Error handling for broken images
- Content Type Detection: Support for MIME type and file extension detection
Sidebar Integration
- SidebarGroup Structure: Integrates with application sidebar system
- Responsive Design: Truncated text with tooltips for long filenames
- Empty States: Graceful handling when no documents are assigned
Component Interface
type DocumentSidebarProps = {
documents: Document[]; // Array of assigned documents
userState: UserState; // User authentication state
};
interface Document {
name: string; // Document display name
url: string; // Document access URL
type?: string; // File type or extension
contentType?: string; // MIME content type
}
type UserState = 'not-logged-in' | 'receiver' | 'admin';
Core Functionality
1. Document Item Rendering
const DocumentItem = ({ doc }: { doc: Document }) => {
const isImage = doc.contentType?.startsWith('image/');
const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {
if (isImage) {
e.preventDefault();
window.open(doc.url, '_blank', 'noopener');
}
};
const iconType = DocumentHandler.getFileIcon(doc.type || doc.contentType || '');
const IconComponent = IconMap[iconType];
return (
<SidebarMenuItem>
<SidebarMenuButton asChild>
<a
href={doc.url}
target="_blank"
rel="noopener noreferrer"
onClick={handleClick}
className="flex items-center gap-2"
>
{isImage ? (
<div className="relative w-4 h-4 overflow-hidden rounded">
<Image
src={doc.url}
alt={doc.name}
width={16}
height={16}
className="object-cover"
crossOrigin="anonymous"
referrerPolicy="no-referrer"
/>
</div>
) : (
<IconComponent className="w-4 h-4 flex-shrink-0" />
)}
<span className="truncate" title={doc.name}>{doc.name}</span>
</a>
</SidebarMenuButton>
</SidebarMenuItem>
);
};
2. Authentication-Based Rendering
const DocumentSidebar = ({ documents, userState }: DocumentSidebarProps) => {
if (userState === 'not-logged-in') {
return <SidebarGroup></SidebarGroup>;
}
if (documents.length === 0) {
return <SidebarGroup></SidebarGroup>;
}
return (
<SidebarGroup>
<SidebarGroupLabel>
<span>Assigned Documents</span>
</SidebarGroupLabel>
<SidebarGroupContent>
<SidebarMenu>
{documents.map((doc, index) => (
<DocumentItem key={index} doc={doc} />
))}
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>
);
};
3. Image Error Handling
// Fallback mechanism for broken images
onError={(e) => {
const target = e.target as HTMLImageElement;
target.style.display = 'none';
const IconFallback = IconMap.Image;
const iconElement = document.createElement('div');
iconElement.className = 'w-4 h-4';
target.parentNode?.appendChild(iconElement);
}}
Integration Examples
Basic Usage
function ChatSidebar({ user, assistant }) {
return (
<Sidebar>
<Documents
documents={assistant.documents}
userState={user ? 'receiver' : 'not-logged-in'}
/>
</Sidebar>
);
}
With Assistant Context
function AssistantInterface({ assistant, user }) {
const getUserState = () => {
if (!user) return 'not-logged-in';
if (user.email === assistant.adminEmail) return 'admin';
return 'receiver';
};
return (
<div className="app-layout">
<AppSidebar>
<Documents
documents={assistant.initialDocuments || []}
userState={getUserState()}
/>
</AppSidebar>
</div>
);
}
Document Handler Integration
File Type Detection
// Uses DocumentHandler utility for icon determination
const iconType = DocumentHandler.getFileIcon(doc.type || doc.contentType || '');
const IconComponent = IconMap[iconType];
// Expected icon types from DocumentHandler:
// - 'pdf', 'image', 'document', 'spreadsheet', 'presentation', 'archive', 'code', etc.
Icon Mapping
// IconMap provides React components for each file type
const IconMap = {
pdf: PdfIcon,
image: ImageIcon,
document: FileTextIcon,
spreadsheet: TableIcon,
// ... more icon mappings
};
Features
Security
- Safe External Links:
rel="noopener noreferrer"for external document access - CORS Handling: Proper cross-origin and referrer policies for images
- XSS Prevention: Safe handling of document URLs and names
Performance
- Lazy Rendering: Only renders when documents exist and user is authenticated
- Optimized Images: Next.js Image component for optimized loading
- Efficient Updates: Component only re-renders when documents or user state changes
Accessibility
- Screen Reader Support: Proper semantic markup with sidebar components
- Keyboard Navigation: Full keyboard accessibility for document links
- Tooltip Support: Full filenames available via title attributes
- Focus Management: Logical tab order through document list
Visual Design
- Consistent Icons: File type-appropriate icons for visual recognition
- Image Previews: Thumbnail previews for image documents
- Truncation: Long filenames handled with ellipsis and tooltips
- Sidebar Integration: Consistent styling with application sidebar theme