@copilotz/chat-ui 0.3.1 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +11 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +11 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/components/chat/ChatUI.tsx","../src/config/chatConfig.ts","../src/components/chat/Message.tsx","../src/lib/chatUtils.ts","../src/components/ui/button.tsx","../src/lib/utils.ts","../src/components/ui/avatar.tsx","../src/components/ui/badge.tsx","../src/components/ui/card.tsx","../src/components/ui/textarea.tsx","../src/components/ui/tooltip.tsx","../src/components/chat/Sidebar.tsx","../src/components/ui/input.tsx","../src/components/ui/sidebar.tsx","../src/hooks/use-mobile.ts","../src/components/ui/separator.tsx","../src/components/ui/sheet.tsx","../src/components/ui/skeleton.tsx","../src/components/ui/dialog.tsx","../src/components/ui/alert-dialog.tsx","../src/components/ui/dropdown-menu.tsx","../src/components/chat/UserMenu.tsx","../src/components/chat/ChatHeader.tsx","../src/components/chat/AgentSelectors.tsx","../src/components/chat/ChatInput.tsx","../src/components/chat/UserContext.tsx","../src/lib/voiceCompose.ts","../src/components/ui/progress.tsx","../src/components/chat/VoiceComposer.tsx","../src/components/chat/UserProfile.tsx","../src/components/ui/scroll-area.tsx","../src/components/chat/ThreadManager.tsx"],"sourcesContent":["export * from './components/chat/ChatUI';\nexport * from './components/chat/ChatHeader';\nexport * from './components/chat/AgentSelectors';\nexport * from './components/chat/ChatInput';\nexport * from './components/chat/Message';\nexport * from './components/chat/Sidebar';\nexport * from './components/chat/ThreadManager';\nexport * from './components/chat/UserContext';\nexport * from './components/chat/UserMenu';\nexport * from './components/chat/UserProfile';\nexport * from './config/chatConfig';\nexport * from './types/chatTypes';\nexport * from './lib/utils';\nexport * from './lib/chatUtils';\n","import React, { useState, useEffect, useRef, useCallback, useMemo } from 'react';\nimport { useVirtualizer } from '@tanstack/react-virtual';\nimport {\n ChatV2Props,\n MediaAttachment,\n MessageActionEvent,\n StateCallback,\n ChatState,\n ChatUserContext,\n} from '../../types/chatTypes';\nimport { defaultChatConfig, mergeConfig } from '../../config/chatConfig';\nimport { Message } from './Message';\nimport { Sidebar } from './Sidebar';\nimport { ChatHeader } from './ChatHeader';\nimport { ChatInput } from './ChatInput';\nimport { TargetAgentSelector } from './AgentSelectors';\nimport { UserProfile } from './UserProfile';\nimport { useChatUserContext } from './UserContext';\nimport { ScrollArea } from '../ui/scroll-area';\nimport { Skeleton } from '../ui/skeleton';\nimport { TooltipProvider } from '../ui/tooltip';\nimport { SidebarProvider, SidebarInset } from '../ui/sidebar';\nimport { Sparkles, ArrowRight, MessageSquare, Lightbulb, Zap, HelpCircle } from 'lucide-react';\n\n// ChatUI is a purely presentational component\nexport const ChatUI: React.FC<ChatV2Props> = ({\n messages = [],\n threads = [],\n currentThreadId = null,\n config: userConfig,\n sidebar: _sidebar,\n isGenerating = false,\n isMessagesLoading = false,\n callbacks = {},\n user,\n assistant,\n suggestions = [],\n messageSuggestions = {},\n agentOptions = [],\n selectedAgentId = null,\n onSelectAgent,\n participantIds,\n onParticipantsChange,\n targetAgentId = null,\n onTargetAgentChange,\n className = '',\n onAddMemory,\n onUpdateMemory,\n onDeleteMemory,\n initialInput,\n onInitialInputConsumed,\n}) => {\n // Merge configuration with defaults\n const config = useMemo(\n () => mergeConfig(defaultChatConfig, userConfig),\n [userConfig]\n );\n\n // Mobile detection\n const [isMobile, setIsMobile] = useState(false);\n\n // Built-in user profile panel state\n const [isUserProfileOpen, setIsUserProfileOpen] = useState(false);\n\n // Try to get user context for custom fields (may not be available if used outside provider)\n let userContext: ChatUserContext | undefined;\n try {\n const contextValue = useChatUserContext();\n userContext = contextValue?.context;\n } catch {\n // ChatUI used outside of ChatUserContextProvider, that's okay\n userContext = undefined;\n }\n\n // Check if desktop on initial render\n const getInitialSidebarState = () => {\n if (typeof globalThis.innerWidth === 'number') {\n return globalThis.innerWidth >= 1024; // Open on desktop (lg+)\n }\n return false;\n };\n\n // Separate input state to avoid full re-renders on every keystroke\n const [inputValue, setInputValue] = useState('');\n const [attachments, setAttachments] = useState<MediaAttachment[]>([]);\n const [expandedMessageIds, setExpandedMessageIds] = useState<Record<string, boolean>>({});\n\n // Internal state for UI only (excluding input to optimize re-renders)\n const [state, setState] = useState<Omit<ChatState, 'input' | 'attachments'>>({\n isRecording: false,\n selectedThreadId: currentThreadId,\n isAtBottom: true,\n showSidebar: getInitialSidebarState(), // Open by default on desktop\n showThreads: false, // No longer used for main sidebar\n editingMessageId: null,\n isSidebarCollapsed: false, // No longer used for main sidebar\n });\n\n // Update internal selected thread if prop changes\n useEffect(() => {\n if (currentThreadId !== state.selectedThreadId) {\n setState(prev => ({ ...prev, selectedThreadId: currentThreadId }));\n }\n }, [currentThreadId]);\n\n // Track if initialInput has been applied\n const initialInputApplied = useRef(false);\n const initialInputConsumedRef = useRef(false);\n\n // Apply initialInput when provided\n useEffect(() => {\n if (initialInput && !initialInputApplied.current) {\n setInputValue(initialInput);\n initialInputApplied.current = true;\n }\n }, [initialInput]);\n\n // Refs\n const scrollAreaRef = useRef<HTMLDivElement>(null);\n\n // Refs for state to avoid recreating callbacks on every state change\n const stateRef = useRef(state);\n const inputValueRef = useRef(inputValue);\n const attachmentsRef = useRef(attachments);\n\n // Keep refs in sync with state\n useEffect(() => { stateRef.current = state; }, [state]);\n useEffect(() => { inputValueRef.current = inputValue; }, [inputValue]);\n useEffect(() => { attachmentsRef.current = attachments; }, [attachments]);\n\n // Mobile custom overlay mount/unmount for smooth transitions\n const [isCustomMounted, setIsCustomMounted] = useState(false);\n const [isCustomVisible, setIsCustomVisible] = useState(false);\n\n // Virtualizer — only renders messages visible in the viewport + overscan buffer\n const virtualizer = useVirtualizer({\n count: messages.length,\n getScrollElement: () => scrollAreaRef.current,\n estimateSize: () => 100,\n overscan: 5,\n });\n\n // Create state callback helpers - uses refs to avoid recreating on every state change\n const createStateCallback = useCallback(\n (setter?: (value: React.SetStateAction<ChatState>) => void): StateCallback<ChatState> => ({\n setState: (newState) => setter?.(newState),\n getState: () => ({\n ...stateRef.current,\n input: inputValueRef.current,\n attachments: attachmentsRef.current,\n }),\n }),\n [] // No dependencies - uses refs for latest state\n );\n\n // Mobile detection effect\n useEffect(() => {\n const checkMobile = () => {\n setIsMobile(globalThis.innerWidth < 1024); // lg breakpoint\n };\n\n checkMobile();\n globalThis.addEventListener('resize', checkMobile);\n return () => globalThis.removeEventListener('resize', checkMobile);\n }, []);\n\n // Animate mobile custom component overlay\n useEffect(() => {\n if (!isMobile || !config.customComponent?.component) return;\n if (state.showSidebar) {\n setIsCustomMounted(true);\n requestAnimationFrame(() => setIsCustomVisible(true));\n } else {\n setIsCustomVisible(false);\n const t = setTimeout(() => setIsCustomMounted(false), 200);\n return () => clearTimeout(t);\n }\n }, [state.showSidebar, isMobile, config.customComponent]);\n\n // Track previous message count to detect initial load vs incremental updates\n const prevMessageCountRef = useRef(0);\n\n // Auto-scroll to bottom on message changes\n useEffect(() => {\n if (messages.length === 0) {\n prevMessageCountRef.current = 0;\n return;\n }\n\n const wasEmpty = prevMessageCountRef.current === 0;\n prevMessageCountRef.current = messages.length;\n\n if (wasEmpty) {\n // Initial load (thread switch) — jump instantly to the bottom\n // Double RAF ensures the virtualizer has committed its layout\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n virtualizer.scrollToIndex(messages.length - 1, { align: 'end' });\n });\n });\n return;\n }\n\n // Incremental update (new message, streaming) — smooth-scroll if at bottom\n if (!state.isAtBottom) return;\n requestAnimationFrame(() => {\n const viewport = scrollAreaRef.current;\n if (!viewport) return;\n try {\n viewport.scrollTo({ top: viewport.scrollHeight, behavior: 'smooth' });\n } catch {\n viewport.scrollTop = viewport.scrollHeight;\n }\n });\n }, [messages, state.isAtBottom, virtualizer]);\n\n useEffect(() => {\n virtualizer.measure();\n }, [expandedMessageIds, virtualizer]);\n\n useEffect(() => {\n const validMessageIds = new Set(messages.map((message) => message.id));\n\n setExpandedMessageIds((prev) => {\n const activeIds = Object.keys(prev);\n const staleIds = activeIds.filter((messageId) => !validMessageIds.has(messageId));\n\n if (staleIds.length === 0) {\n return prev;\n }\n\n const next = { ...prev };\n staleIds.forEach((messageId) => {\n delete next[messageId];\n });\n return next;\n });\n }, [messages]);\n\n // Handle scroll position — only update state when the value actually changes\n const handleScroll = useCallback((e: React.UIEvent<HTMLDivElement>) => {\n const { scrollTop, scrollHeight, clientHeight } = e.currentTarget;\n const isAtBottom = scrollHeight - scrollTop - clientHeight < 50;\n setState(prev => {\n if (prev.isAtBottom === isAtBottom) return prev;\n return { ...prev, isAtBottom };\n });\n }, []);\n\n // Message handling\n const handleSendMessage = useCallback((\n content: string,\n messageAttachments: MediaAttachment[] = []\n ) => {\n if (!content.trim() && messageAttachments.length === 0) return;\n \n // Call external callback\n callbacks.onSendMessage?.(content, messageAttachments, createStateCallback());\n\n // Mark initial input as consumed when message is sent\n if (initialInputApplied.current && !initialInputConsumedRef.current) {\n initialInputConsumedRef.current = true;\n onInitialInputConsumed?.();\n }\n\n // Clear input (using separate state for performance)\n setInputValue('');\n setAttachments([]);\n }, [callbacks, createStateCallback, onInitialInputConsumed]);\n\n // Message actions\n const handleMessageAction = useCallback((event: MessageActionEvent) => {\n const { action, messageId, content } = event;\n\n switch (action) {\n case 'copy':\n callbacks.onCopyMessage?.(messageId, content || '', createStateCallback());\n break;\n case 'edit':\n if (content) {\n callbacks.onEditMessage?.(messageId, content, createStateCallback());\n }\n break;\n case 'regenerate':\n callbacks.onRegenerateMessage?.(messageId, createStateCallback());\n break;\n case 'delete':\n callbacks.onDeleteMessage?.(messageId, createStateCallback());\n break;\n }\n }, [callbacks, createStateCallback]);\n\n const handleToggleMessageExpansion = useCallback((messageId: string) => {\n setExpandedMessageIds((prev) => {\n if (prev[messageId]) {\n const next = { ...prev };\n delete next[messageId];\n return next;\n }\n\n return {\n ...prev,\n [messageId]: true,\n };\n });\n }, []);\n\n // Thread management\n const handleCreateThread = useCallback((title?: string) => {\n callbacks.onCreateThread?.(title, createStateCallback());\n }, [callbacks, createStateCallback]);\n\n const handleSelectThread = useCallback((threadId: string) => {\n callbacks.onSelectThread?.(threadId, createStateCallback());\n }, [callbacks, createStateCallback]);\n\n const handleRenameThread = useCallback((threadId: string, newTitle: string) => {\n callbacks.onRenameThread?.(threadId, newTitle, createStateCallback());\n }, [callbacks, createStateCallback]);\n\n const handleDeleteThread = useCallback((threadId: string) => {\n callbacks.onDeleteThread?.(threadId, createStateCallback());\n }, [callbacks, createStateCallback]);\n\n const handleArchiveThread = useCallback((threadId: string) => {\n callbacks.onArchiveThread?.(threadId, createStateCallback());\n }, [callbacks, createStateCallback]);\n\n // Close sidebar handler\n const closeSidebar = useCallback(() => {\n setState(prev => ({ ...prev, showSidebar: false }));\n }, []);\n\n const handleCustomComponentToggle = useCallback(() => {\n setState(prev => ({ ...prev, showSidebar: !prev.showSidebar }));\n }, []);\n\n const sidebarUser = useMemo(() => user ? {\n id: user.id,\n name: user.name,\n email: user.email,\n avatar: user.avatar,\n } : null, [user?.id, user?.name, user?.email, user?.avatar]);\n\n const handleViewProfile = useCallback(() => {\n setIsUserProfileOpen(true);\n callbacks.onViewProfile?.();\n }, [callbacks.onViewProfile]);\n\n const sidebarUserMenuCallbacks = useMemo(() => ({\n onViewProfile: handleViewProfile,\n onOpenSettings: callbacks.onOpenSettings,\n onThemeChange: callbacks.onThemeChange,\n onLogout: callbacks.onLogout,\n }), [handleViewProfile, callbacks.onOpenSettings, callbacks.onThemeChange, callbacks.onLogout]);\n\n // Render custom component with props if it's a function\n const renderCustomComponent = useCallback(() => {\n const component = config?.customComponent?.component;\n if (!component) return null;\n if (typeof component === 'function') {\n return component({ onClose: closeSidebar, isMobile });\n }\n return component;\n }, [config?.customComponent?.component, closeSidebar, isMobile]);\n\n // Icon components for suggestion cards (cycle through these)\n const SuggestionIconComponents = [MessageSquare, Lightbulb, Zap, HelpCircle];\n\n // Render suggestions\n const renderSuggestions = () => {\n if (messages.length > 0 || !suggestions.length) return null;\n\n return (\n <div className=\"flex flex-col items-center justify-center min-h-[60vh] py-8 px-4\">\n {/* Hero section */}\n <div className=\"text-center mb-8\">\n <div className=\"inline-flex items-center justify-center w-14 h-14 rounded-2xl bg-gradient-to-br from-primary/20 to-primary/5 mb-4 shadow-sm\">\n <Sparkles className=\"w-7 h-7 text-primary\" />\n </div>\n <h2 className=\"text-xl font-semibold mb-2\">{config.branding.title}</h2>\n <p className=\"text-muted-foreground text-sm max-w-md\">{config.branding.subtitle}</p>\n </div>\n\n {/* Suggestion cards */}\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-3 w-full max-w-2xl\">\n {suggestions.map((suggestion, index) => (\n <button\n key={index}\n type=\"button\"\n onClick={() => handleSendMessage(suggestion)}\n className=\"group relative flex items-start gap-3 p-4 text-left rounded-xl border bg-card hover:bg-accent/50 hover:border-accent transition-all duration-200 hover:shadow-sm\"\n >\n {(() => {\n const IconComponent = SuggestionIconComponents[index % SuggestionIconComponents.length];\n return (\n <div className=\"flex items-center justify-center w-8 h-8 rounded-lg bg-primary/10 text-primary shrink-0 group-hover:bg-primary/15 transition-colors\">\n <IconComponent className=\"h-4 w-4\" />\n </div>\n );\n })()}\n <div className=\"flex-1 min-w-0 pr-6\">\n <p className=\"text-sm font-medium leading-snug line-clamp-2\">{suggestion}</p>\n </div>\n <ArrowRight className=\"absolute right-4 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground opacity-0 group-hover:opacity-100 transition-opacity\" />\n </button>\n ))}\n </div>\n </div>\n );\n };\n\n const renderInlineSuggestions = (messageId: string) => {\n const items = messageSuggestions?.[messageId];\n if (!items || items.length === 0) return null;\n const inlineSuggestionOffsetClass = config.ui.showAvatars\n ? (config.ui.compactMode ? 'ml-9' : 'ml-11')\n : '';\n\n return (\n <div className={`flex flex-wrap gap-2 mt-2 ${inlineSuggestionOffsetClass}`}>\n {items.map((suggestion, index) => (\n <button\n key={`${messageId}-suggestion-${index}`}\n type=\"button\"\n onClick={() => handleSendMessage(suggestion)}\n className=\"group inline-flex items-center gap-1.5 px-3 py-1.5 text-sm rounded-full border border-border bg-background hover:bg-accent hover:border-accent-foreground/20 transition-all duration-150 text-foreground/80 hover:text-foreground\"\n >\n <Sparkles className=\"h-3 w-3 text-primary opacity-70 group-hover:opacity-100\" />\n <span className=\"max-w-[200px] truncate\">{suggestion}</span>\n </button>\n ))}\n </div>\n );\n };\n\n const renderMessageLoadingSkeleton = () => (\n <div className=\"space-y-6 py-2\">\n {[0, 1, 2, 3].map((index) => {\n const isUserRow = index % 2 === 1;\n return (\n <div\n key={`message-skeleton-${index}`}\n className={`flex gap-3 ${isUserRow ? 'justify-end' : 'justify-start'}`}\n >\n {!isUserRow && <Skeleton className=\"h-8 w-8 rounded-full shrink-0\" />}\n <div className={`space-y-2 ${isUserRow ? 'w-[70%]' : 'w-[75%]'}`}>\n <Skeleton className=\"h-4 w-24\" />\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-4 w-[85%]\" />\n </div>\n {isUserRow && <Skeleton className=\"h-8 w-8 rounded-full shrink-0\" />}\n </div>\n );\n })}\n </div>\n );\n\n const isMultiAgentMode = config.agentSelector?.mode === 'multi';\n\n // Stable props object for Message components — prevents unnecessary re-renders\n // when the virtualizer re-evaluates which items to show\n const messageProps = useMemo(() => ({\n userAvatar: user?.avatar,\n userName: user?.name,\n assistantAvatar: assistant?.avatar,\n assistantName: assistant?.name,\n showTimestamp: config.ui.showTimestamps,\n showAvatar: config.ui.showAvatars,\n enableCopy: config.features.enableMessageCopy,\n enableEdit: config.features.enableMessageEditing,\n enableRegenerate: config.features.enableRegeneration,\n enableToolCallsDisplay: config.features.enableToolCallsDisplay,\n compactMode: config.ui.compactMode,\n onAction: handleMessageAction,\n toolUsedLabel: config.labels.toolUsed,\n thinkingLabel: config.labels.thinking,\n showMoreLabel: config.labels.showMoreMessage,\n showLessLabel: config.labels.showLessMessage,\n collapseLongMessages: config.ui.collapseLongMessages,\n collapseLongMessagesForUserOnly: config.ui.collapseLongMessagesForUserOnly,\n longMessagePreviewChars: config.ui.longMessagePreviewChars,\n longMessageChunkChars: config.ui.longMessageChunkChars,\n renderUserMarkdown: config.ui.renderUserMarkdown,\n markdown: config.markdown,\n onToggleExpanded: handleToggleMessageExpansion,\n agentOptions: isMultiAgentMode ? agentOptions : undefined,\n }), [\n user?.avatar,\n user?.name,\n assistant?.avatar,\n assistant?.name,\n isMultiAgentMode,\n agentOptions,\n config.ui.showTimestamps,\n config.ui.showAvatars,\n config.ui.compactMode,\n config.features.enableMessageCopy,\n config.features.enableMessageEditing,\n config.features.enableRegeneration,\n config.features.enableToolCallsDisplay,\n config.labels.toolUsed,\n config.labels.thinking,\n config.labels.showMoreMessage,\n config.labels.showLessMessage,\n config.ui.collapseLongMessages,\n config.ui.collapseLongMessagesForUserOnly,\n config.ui.longMessagePreviewChars,\n config.ui.longMessageChunkChars,\n config.ui.renderUserMarkdown,\n config.markdown,\n handleMessageAction,\n handleToggleMessageExpansion,\n ]);\n\n const shouldShowAgentSelector = Boolean(\n config.agentSelector?.enabled &&\n agentOptions.length > 0 &&\n (!config.agentSelector?.hideIfSingle || agentOptions.length > 1) &&\n (isMultiAgentMode ? onParticipantsChange : onSelectAgent)\n );\n\n return (\n <TooltipProvider>\n <SidebarProvider defaultOpen>\n <div className={`flex h-[100svh] md:h-screen bg-background w-full overflow-hidden ${className}`}>\n \n <Sidebar\n threads={threads}\n currentThreadId={state.selectedThreadId}\n config={config}\n onCreateThread={handleCreateThread}\n onSelectThread={handleSelectThread}\n onRenameThread={handleRenameThread}\n onDeleteThread={handleDeleteThread}\n onArchiveThread={handleArchiveThread}\n // User menu props\n user={sidebarUser}\n userMenuCallbacks={sidebarUserMenuCallbacks}\n currentTheme={config.ui.theme === 'auto' ? 'system' : config.ui.theme}\n showThemeOptions={!!callbacks.onThemeChange}\n />\n\n <SidebarInset>\n <div className=\"flex flex-col h-full min-h-0\">\n {/* Header */}\n <ChatHeader\n config={config}\n currentThreadTitle={threads.find(t => t.id === state.selectedThreadId)?.title}\n // onSidebarToggle is now handled by SidebarTrigger inside ChatHeader\n isMobile={isMobile}\n onCustomComponentToggle={handleCustomComponentToggle}\n onNewThread={handleCreateThread}\n showCustomComponentButton={!!config?.customComponent?.component}\n showAgentSelector={shouldShowAgentSelector}\n isMultiAgentMode={isMultiAgentMode}\n agentOptions={agentOptions}\n selectedAgentId={selectedAgentId}\n onSelectAgent={onSelectAgent}\n participantIds={participantIds}\n onParticipantsChange={onParticipantsChange}\n />\n\n <div className=\"flex flex-1 flex-row min-h-0 overflow-hidden\">\n {/* Main Chat Area */}\n <div className=\"flex-1 flex flex-col min-h-0\">\n {/* Messages — contain: strict prevents reflow from propagating to/from the input */}\n <ScrollArea\n ref={scrollAreaRef}\n className=\"flex-1 min-h-0\"\n viewportClassName=\"p-4 overscroll-contain\"\n onScrollCapture={handleScroll}\n style={{ contain: 'strict' }}\n >\n <div className=\"max-w-4xl mx-auto pb-4\">\n {isMessagesLoading ? (\n renderMessageLoadingSkeleton()\n ) : messages.length === 0 ? (\n renderSuggestions()\n ) : (\n <div\n style={{\n height: `${virtualizer.getTotalSize()}px`,\n width: '100%',\n position: 'relative',\n }}\n >\n {virtualizer.getVirtualItems().map((virtualRow) => {\n const message = messages[virtualRow.index];\n const prevMessage = virtualRow.index > 0 ? messages[virtualRow.index - 1] : null;\n const isGrouped = prevMessage !== null && prevMessage.role === message.role;\n\n return (\n <div\n key={message.id}\n data-index={virtualRow.index}\n ref={virtualizer.measureElement}\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n width: '100%',\n transform: `translateY(${virtualRow.start}px)`,\n }}\n >\n <div className={virtualRow.index === 0 ? '' : isGrouped ? 'pt-2' : 'pt-4'}>\n <Message\n message={message}\n {...messageProps}\n isGrouped={isGrouped}\n isExpanded={Boolean(expandedMessageIds[message.id])}\n />\n {message.role === 'assistant' && renderInlineSuggestions(message.id)}\n </div>\n </div>\n );\n })}\n </div>\n )}\n </div>\n </ScrollArea>\n\n {/* Input */}\n <div className=\"bg-background pb-[env(safe-area-inset-bottom)]\">\n {/* Target agent selector for multi-agent mode */}\n {isMultiAgentMode && shouldShowAgentSelector && onTargetAgentChange && (\n <div className=\"px-4 pt-1\">\n <TargetAgentSelector\n agents={participantIds && participantIds.length > 0\n ? agentOptions.filter(a => participantIds.includes(a.id))\n : agentOptions}\n targetAgentId={targetAgentId}\n onTargetChange={onTargetAgentChange}\n placeholder={config.agentSelector?.label || 'Select agent'}\n disabled={isGenerating}\n />\n </div>\n )}\n <ChatInput\n value={inputValue}\n onChange={(value) => {\n setInputValue(value);\n // Mark initial input as consumed when user modifies it\n if (initialInputApplied.current && !initialInputConsumedRef.current) {\n initialInputConsumedRef.current = true;\n onInitialInputConsumed?.();\n }\n }}\n onSubmit={handleSendMessage}\n attachments={attachments}\n onAttachmentsChange={setAttachments}\n placeholder={config.labels.inputPlaceholder}\n disabled={false}\n isGenerating={isGenerating}\n onStopGeneration={callbacks.onStopGeneration}\n enableFileUpload={config.features.enableFileUpload}\n enableAudioRecording={config.features.enableAudioRecording}\n maxAttachments={config.features.maxAttachments}\n maxFileSize={config.features.maxFileSize}\n config={config}\n mentionAgents={participantIds && participantIds.length > 0\n ? agentOptions.filter(a => participantIds.includes(a.id))\n : agentOptions}\n onTargetAgentChange={onTargetAgentChange}\n />\n </div>\n </div>\n\n {/* Right sidebar custom component for desktop */}\n {config?.customComponent?.component && !isMobile && (\n <div\n className=\"h-full transition-all duration-300 ease-in-out overflow-hidden\"\n style={{ width: state.showSidebar ? (config.customComponent.panelWidth ?? 320) : 0 }}\n >\n {state.showSidebar && (\n <div\n className=\"h-full overflow-hidden border-l bg-background animate-in slide-in-from-right-4 duration-300\"\n style={{ width: config.customComponent.panelWidth ?? 320 }}\n >\n {renderCustomComponent()}\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n </SidebarInset>\n\n {/* Mobile custom sidebar overlay with smooth transitions (slides from right) */}\n {isCustomMounted && config.customComponent?.component && isMobile && (\n <div className=\"fixed inset-0 z-50\">\n {/* Backdrop */}\n <div\n className={`absolute inset-0 bg-background/80 backdrop-blur-sm transition-opacity duration-200 ease-out ${\n isCustomVisible ? 'opacity-100' : 'opacity-0'\n }`}\n style={{ willChange: 'opacity' }}\n onClick={closeSidebar}\n />\n {/* Panel - slides from right */}\n <div\n className={`absolute top-0 right-0 h-full w-full bg-background transform-gpu transition-transform duration-200 ease-out ${\n isCustomVisible ? 'translate-x-0' : 'translate-x-full'\n }`}\n style={{ willChange: 'transform' }}\n >\n <div className=\"h-full overflow-hidden\">\n {renderCustomComponent()}\n </div>\n </div>\n </div>\n )}\n\n {/* Built-in User Profile Panel - only render when open to avoid Radix focus conflicts */}\n {isUserProfileOpen && (\n <UserProfile\n isOpen={isUserProfileOpen}\n onClose={() => setIsUserProfileOpen(false)}\n user={user ? {\n id: user.id,\n name: user.name,\n email: user.email,\n avatar: user.avatar,\n } : null}\n customFields={userContext?.customFields}\n memories={userContext?.memories?.items}\n onLogout={callbacks.onLogout}\n onAddMemory={onAddMemory}\n onUpdateMemory={onUpdateMemory}\n onDeleteMemory={onDeleteMemory}\n />\n )}\n </div>\n </SidebarProvider>\n </TooltipProvider>\n );\n};\n","import { ChatConfig } from '../types/chatTypes';\n\n// Default configuration\nexport const defaultChatConfig: Required<ChatConfig> = {\n\n branding: {\n logo: null,\n avatar: null,\n title: 'Chat Assistant',\n subtitle: 'How can I help you today?',\n },\n\n agentSelector: {\n enabled: false,\n label: 'Select agent',\n hideIfSingle: true,\n },\n \n labels: {\n inputPlaceholder: 'Type your message...',\n sendButton: 'Send',\n sendMessageTooltip: 'Send message',\n newThread: 'New Conversation',\n deleteThread: 'Delete Conversation',\n copyMessage: 'Copy',\n editMessage: 'Edit',\n regenerateMessage: 'Regenerate',\n stopGeneration: 'Stop',\n stopGenerationTooltip: 'Stop generation',\n attachFiles: 'Attach Files',\n attachFileTooltip: 'Attach file',\n recordAudio: 'Record Audio',\n recordAudioTooltip: 'Record audio',\n voiceEnter: 'Voice input',\n voiceExit: 'Use keyboard',\n voiceTitle: 'Voice',\n voiceIdle: 'Tap the mic to record',\n voicePreparing: 'Preparing microphone...',\n voiceWaiting: 'Waiting for speech...',\n voiceListening: 'Listening...',\n voiceFinishing: 'Finishing capture...',\n voiceReview: 'Ready to send',\n voiceSending: 'Sending...',\n voiceReviewArmedHint: 'Still listening. Speak to add more before it sends.',\n voiceReviewPausedHint: 'Tap the mic to keep adding to this message.',\n voiceStart: 'Start recording',\n voiceStop: 'Stop recording',\n voiceSendNow: 'Send now',\n voiceCancel: 'Cancel',\n voiceDiscard: 'Delete recording',\n voiceRecordAgain: 'Continue recording',\n voiceAutoSendIn: 'Auto-sends in {{seconds}}s',\n voiceTranscriptPending: 'Transcript unavailable',\n voicePermissionDenied: 'Microphone access was denied.',\n voiceCaptureError: 'Unable to capture audio.',\n // Header labels\n exportData: 'Export data',\n importData: 'Import data',\n clearAll: 'Clear all',\n sidebarToggle: 'Menu',\n customComponentToggle: 'Toggle',\n settings: 'Settings',\n toggleDarkMode: 'Toggle Dark Mode',\n lightMode: 'Light Mode',\n darkMode: 'Dark Mode',\n // Sidebar labels\n newChat: 'New Conversation',\n search: 'Search conversations...',\n customComponentLabel: 'Custom',\n showArchived: 'Show Archived',\n hideArchived: 'Hide Archived',\n noThreadsFound: 'No conversations found',\n noThreadsYet: 'No conversations yet',\n deleteConfirmTitle: 'Delete Conversation',\n deleteConfirmDescription: 'Are you sure you want to delete this conversation? This action cannot be undone. All messages will be permanently lost.',\n renameThread: 'Rename',\n archiveThread: 'Archive',\n unarchiveThread: 'Unarchive',\n today: 'Today',\n yesterday: 'Yesterday',\n createNewThread: 'Create New Conversation',\n threadNamePlaceholder: 'Conversation name (optional)',\n cancel: 'Cancel',\n create: 'Create Conversation',\n footerLabel: 'Assistant can make mistakes. Check the AI results.',\n toolUsed: 'Tool Used',\n daysAgo: 'days ago',\n inputHelpText: 'Press Enter to send, Shift+Enter to add a new line.',\n thinking: 'Thinking...',\n defaultThreadName: 'Main Thread',\n showMoreMessage: 'Show more',\n showLessMessage: 'Show less',\n },\n \n features: {\n enableThreads: true,\n enableFileUpload: true,\n enableAudioRecording: true,\n enableMessageEditing: true,\n enableMessageCopy: true,\n enableRegeneration: true,\n enableToolCallsDisplay: true,\n maxAttachments: 4,\n maxFileSize: 10 * 1024 * 1024, // 10MB\n },\n \n ui: {\n theme: 'auto' as const,\n showTimestamps: false,\n showAvatars: true,\n compactMode: false,\n showWordCount: false,\n collapseLongMessages: false,\n collapseLongMessagesForUserOnly: false,\n longMessagePreviewChars: 4000,\n longMessageChunkChars: 12000,\n renderUserMarkdown: true,\n },\n\n markdown: {\n remarkPlugins: [],\n rehypePlugins: [],\n components: {},\n },\n\n voiceCompose: {\n enabled: false,\n defaultMode: 'text',\n reviewMode: 'manual',\n autoSendDelayMs: 5000,\n persistComposer: true,\n showTranscriptPreview: true,\n transcriptMode: 'final-only',\n maxRecordingMs: 60000,\n createProvider: undefined,\n },\n \n customComponent: {},\n headerActions: null,\n};\n\n// Deep merge function for configurations\nexport function mergeConfig(_baseConfig: ChatConfig, userConfig?: Partial<ChatConfig>): Required<ChatConfig> {\n if (!userConfig) return defaultChatConfig;\n\n return {\n branding: {\n ...defaultChatConfig.branding,\n ...userConfig.branding,\n },\n labels: {\n ...defaultChatConfig.labels,\n ...userConfig.labels,\n },\n features: {\n ...defaultChatConfig.features,\n ...userConfig.features,\n },\n ui: {\n ...defaultChatConfig.ui,\n ...userConfig.ui,\n },\n markdown: {\n ...defaultChatConfig.markdown,\n ...userConfig.markdown,\n },\n voiceCompose: {\n ...defaultChatConfig.voiceCompose,\n ...userConfig.voiceCompose,\n },\n agentSelector: {\n ...defaultChatConfig.agentSelector,\n ...userConfig.agentSelector,\n },\n customComponent: userConfig.customComponent || defaultChatConfig.customComponent,\n headerActions: userConfig.headerActions || defaultChatConfig.headerActions,\n };\n}\n\n","import React, { useState, useMemo, useEffect, memo } from 'react';\nimport ReactMarkdown, { type Components } from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport rehypeHighlight from 'rehype-highlight';\nimport { ChatMarkdownConfig, ChatMessage, AgentOption, MediaAttachment, ToolCall, MessageActionEvent } from '../../types/chatTypes';\nimport { getAgentColor, getAgentInitials } from '../../lib/chatUtils';\nimport { Button } from '../ui/button';\nimport { Avatar, AvatarFallback, AvatarImage } from '../ui/avatar';\nimport { Badge } from '../ui/badge';\nimport { Card, CardContent } from '../ui/card';\nimport { Textarea } from '../ui/textarea';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '../ui/tooltip';\nimport { createObjectUrlFromDataUrl } from '../../lib/utils';\nimport {\n Copy,\n Edit,\n RotateCcw,\n Check,\n X,\n Wrench,\n Clock,\n ChevronRight,\n ChevronDown,\n Brain\n} from 'lucide-react';\n\n\ninterface MessageProps {\n message: ChatMessage;\n isUser?: boolean;\n userAvatar?: string;\n userName?: string;\n assistantAvatar?: React.ReactNode;\n assistantName?: string;\n showTimestamp?: boolean;\n showAvatar?: boolean;\n enableCopy?: boolean;\n enableEdit?: boolean;\n enableRegenerate?: boolean;\n enableToolCallsDisplay?: boolean;\n compactMode?: boolean;\n onAction?: (event: MessageActionEvent) => void;\n className?: string;\n toolUsedLabel?: string;\n thinkingLabel?: string;\n showMoreLabel?: string;\n showLessLabel?: string;\n collapseLongMessages?: boolean;\n collapseLongMessagesForUserOnly?: boolean;\n longMessagePreviewChars?: number;\n longMessageChunkChars?: number;\n renderUserMarkdown?: boolean;\n markdown?: ChatMarkdownConfig;\n isExpanded?: boolean;\n onToggleExpanded?: (messageId: string) => void;\n /** When true, hides the avatar and name (for grouped consecutive messages from same sender) */\n isGrouped?: boolean;\n /** Available agents for resolving multi-agent display (colors, avatars) */\n agentOptions?: AgentOption[];\n}\n\n// Thinking indicator component - memoized since it's rendered during streaming\nconst ThinkingIndicator: React.FC<{ label?: string }> = memo(function ThinkingIndicator({ label = 'Thinking...' }: { label?: string }) {\n return (\n <div className=\"flex items-center gap-2 py-2\">\n <div className=\"flex gap-1\">\n <span \n className=\"inline-block w-2 h-2 bg-primary rounded-full animate-bounce\" \n style={{ animationDelay: '0ms' }} \n />\n <span \n className=\"inline-block w-2 h-2 bg-primary rounded-full animate-bounce\" \n style={{ animationDelay: '150ms' }} \n />\n <span \n className=\"inline-block w-2 h-2 bg-primary rounded-full animate-bounce\" \n style={{ animationDelay: '300ms' }} \n />\n </div>\n <span className=\"text-sm text-muted-foreground animate-pulse\">{label}</span>\n </div>\n );\n});\n\n// Claude-like collapsible reasoning/thinking block\nconst ThinkingBlock: React.FC<{\n reasoning: string;\n isStreaming?: boolean;\n label?: string;\n}> = memo(function ThinkingBlock({ reasoning, isStreaming = false, label = 'Thinking...' }) {\n const [isOpen, setIsOpen] = useState(isStreaming);\n\n useEffect(() => {\n if (isStreaming) setIsOpen(true);\n }, [isStreaming]);\n\n const finishedLabel = label.replace(/\\.{3}$/, '');\n\n return (\n <div className={`mb-3 rounded-lg border ${isStreaming ? 'border-primary/40 bg-primary/5' : 'border-border/60 bg-muted/30'} overflow-hidden transition-colors duration-300`}>\n <button\n type=\"button\"\n className=\"flex w-full items-center gap-2 px-3 py-2 text-left text-sm font-medium text-muted-foreground hover:text-foreground transition-colors\"\n onClick={() => setIsOpen(!isOpen)}\n >\n <Brain className={`h-4 w-4 flex-shrink-0 ${isStreaming ? 'text-primary animate-pulse' : 'text-muted-foreground'}`} />\n <span className=\"flex-1\">\n {isStreaming ? label : finishedLabel}\n </span>\n {isStreaming && (\n <div className=\"flex gap-0.5 mr-1\">\n <span className=\"inline-block w-1 h-1 bg-primary rounded-full animate-bounce\" style={{ animationDelay: '0ms' }} />\n <span className=\"inline-block w-1 h-1 bg-primary rounded-full animate-bounce\" style={{ animationDelay: '150ms' }} />\n <span className=\"inline-block w-1 h-1 bg-primary rounded-full animate-bounce\" style={{ animationDelay: '300ms' }} />\n </div>\n )}\n {isOpen ? <ChevronDown className=\"h-3 w-3 flex-shrink-0\" /> : <ChevronRight className=\"h-3 w-3 flex-shrink-0\" />}\n </button>\n {isOpen && (\n <div className=\"px-3 pb-3 text-sm text-muted-foreground leading-relaxed whitespace-pre-wrap break-words border-t border-border/40\">\n <div className=\"pt-2\">\n {reasoning}\n {isStreaming && <span className=\"inline-block w-1.5 h-3.5 bg-primary/60 animate-pulse ml-0.5\" />}\n </div>\n </div>\n )}\n </div>\n );\n});\n\n// Memoized markdown components configuration to prevent recreation on every render\nconst defaultMarkdownComponents: Components = {\n code: ({ node, className, children, ...props }: any) => {\n const inline = (props as { inline?: boolean }).inline;\n const match = /language-(\\w+)/.exec(className || '');\n return !inline && match ? (\n <pre className=\"relative\">\n <code className={className} {...props}>\n {children}\n </code>\n </pre>\n ) : (\n <code className=\"bg-muted px-1 py-0.5 rounded text-sm\" {...props}>\n {children}\n </code>\n );\n },\n};\n\n// Memoized plugins arrays to prevent recreation\nconst remarkPluginsDefault = [remarkGfm] as NonNullable<ChatMarkdownConfig['remarkPlugins']>;\nconst rehypePluginsDefault = [rehypeHighlight] as NonNullable<ChatMarkdownConfig['rehypePlugins']>;\nconst rehypePluginsEmpty = [] as NonNullable<ChatMarkdownConfig['rehypePlugins']>;\n\nconst getPlainTextChunks = (content: string, chunkSize: number): string[] => {\n if (chunkSize <= 0 || content.length <= chunkSize) {\n return [content];\n }\n\n const chunks: string[] = [];\n let start = 0;\n\n while (start < content.length) {\n let end = Math.min(start + chunkSize, content.length);\n\n if (end < content.length) {\n const splitAt = content.lastIndexOf('\\n', end);\n if (splitAt > start + Math.floor(chunkSize / 2)) {\n end = splitAt + 1;\n }\n }\n\n chunks.push(content.slice(start, end));\n start = end;\n }\n\n return chunks;\n};\n\nconst hasCodeBlocks = (content: string): boolean => /(^|\\n)(```|~~~)/.test(content);\n\nconst getCollapsedPreview = (content: string, previewChars: number, previewOverride?: string): string => {\n if (previewOverride && previewOverride.trim().length > 0) {\n const normalizedPreview = previewOverride.trimEnd();\n return normalizedPreview.endsWith('...') ? normalizedPreview : `${normalizedPreview}...`;\n }\n\n if (content.length <= previewChars) {\n return content;\n }\n\n return `${content.slice(0, previewChars).trimEnd()}...`;\n};\n\nconst LongContentShell: React.FC<{\n children: React.ReactNode;\n className: string;\n style?: React.CSSProperties;\n}> = memo(function LongContentShell({ children, className, style }) {\n return (\n <div className={className} style={style}>\n {children}\n </div>\n );\n});\n\nconst PlainTextContent: React.FC<{\n content: string;\n className?: string;\n chunkSize?: number;\n style?: React.CSSProperties;\n}> = memo(function PlainTextContent({\n content,\n className = '',\n chunkSize = 12000,\n style,\n}) {\n const chunks = useMemo(() => getPlainTextChunks(content, chunkSize), [content, chunkSize]);\n\n return (\n <LongContentShell\n className={`text-sm leading-6 whitespace-pre-wrap break-words ${className}`.trim()}\n style={style}\n >\n {chunks.map((chunk, index) => (\n <React.Fragment key={index}>{chunk}</React.Fragment>\n ))}\n </LongContentShell>\n );\n});\n\n// Streaming text component for real-time markdown rendering - memoized to prevent unnecessary re-renders\nconst StreamingText: React.FC<{\n content: string;\n isStreaming?: boolean;\n thinkingLabel?: string;\n className?: string;\n renderMarkdown?: boolean;\n markdown?: ChatMarkdownConfig;\n plainTextChunkChars?: number;\n contentStyle?: React.CSSProperties;\n hideThinkingIndicator?: boolean;\n}> = memo(function StreamingText({\n content,\n isStreaming = false,\n thinkingLabel = 'Thinking...',\n className = '',\n renderMarkdown = true,\n markdown,\n plainTextChunkChars = 12000,\n contentStyle,\n hideThinkingIndicator = false,\n}: {\n content: string;\n isStreaming?: boolean;\n thinkingLabel?: string;\n className?: string;\n renderMarkdown?: boolean;\n markdown?: ChatMarkdownConfig;\n plainTextChunkChars?: number;\n contentStyle?: React.CSSProperties;\n hideThinkingIndicator?: boolean;\n}) {\n const hasContent = content.trim().length > 0;\n const enableSyntaxHighlight = renderMarkdown && !isStreaming && hasCodeBlocks(content);\n const mergedComponents = useMemo<Components>(\n () => ({\n ...defaultMarkdownComponents,\n ...markdown?.components,\n }),\n [markdown?.components],\n );\n const mergedRemarkPlugins = useMemo<NonNullable<ChatMarkdownConfig['remarkPlugins']>>(\n () => [\n ...remarkPluginsDefault,\n ...(markdown?.remarkPlugins ?? []),\n ],\n [markdown?.remarkPlugins],\n );\n const mergedRehypePlugins = useMemo<NonNullable<ChatMarkdownConfig['rehypePlugins']>>(\n () => [\n ...(enableSyntaxHighlight ? rehypePluginsDefault : rehypePluginsEmpty),\n ...(markdown?.rehypePlugins ?? []),\n ],\n [enableSyntaxHighlight, markdown?.rehypePlugins],\n );\n\n return (\n <>\n {hasContent ? (\n renderMarkdown ? (\n <LongContentShell\n className={`prose prose-sm max-w-none dark:prose-invert break-words ${className}`.trim()}\n style={contentStyle}\n >\n <ReactMarkdown\n remarkPlugins={mergedRemarkPlugins}\n rehypePlugins={mergedRehypePlugins}\n components={mergedComponents}\n >\n {content}\n </ReactMarkdown>\n </LongContentShell>\n ) : (\n <PlainTextContent\n content={content}\n className={className}\n chunkSize={plainTextChunkChars}\n style={contentStyle}\n />\n )\n ) : isStreaming && !hideThinkingIndicator ? (\n <ThinkingIndicator label={thinkingLabel} />\n ) : null}\n {isStreaming && hasContent && (\n <span className=\"inline-block w-2 h-4 bg-primary animate-pulse ml-1\" />\n )}\n </>\n );\n});\n\n// Media attachment renderer - memoized to prevent unnecessary re-renders\nconst MediaRenderer: React.FC<{ attachment: MediaAttachment }> = memo(function MediaRenderer({ attachment }) {\n const [audioPlaybackSrc, setAudioPlaybackSrc] = useState(attachment.dataUrl);\n\n useEffect(() => {\n if (attachment.kind !== 'audio' || !attachment.dataUrl.startsWith('data:')) {\n setAudioPlaybackSrc(attachment.dataUrl);\n return;\n }\n\n const objectUrl = createObjectUrlFromDataUrl(attachment.dataUrl);\n if (!objectUrl) {\n setAudioPlaybackSrc(attachment.dataUrl);\n return;\n }\n\n setAudioPlaybackSrc(objectUrl);\n\n return () => {\n URL.revokeObjectURL(objectUrl);\n };\n }, [attachment.kind, attachment.dataUrl]);\n\n const formatDuration = (ms?: number) => {\n if (!ms) return '';\n const seconds = Math.floor(ms / 1000);\n const minutes = Math.floor(seconds / 60);\n return `${minutes}:${(seconds % 60).toString().padStart(2, '0')}`;\n };\n\n switch (attachment.kind) {\n case 'image':\n return (\n <div className=\"relative rounded-lg overflow-hidden border bg-muted/20 max-w-md\">\n <img\n src={attachment.dataUrl}\n alt={attachment.fileName || 'Attachment'}\n className=\"w-full h-auto object-cover\"\n loading=\"lazy\"\n />\n {attachment.fileName && (\n <div className=\"absolute bottom-0 left-0 right-0 bg-black/50 text-white text-xs p-2\">\n {attachment.fileName}\n </div>\n )}\n </div>\n );\n\n case 'audio':\n return (\n <div className=\"flex w-full max-w-md py-0 min-w-64 items-center gap-3\">\n <audio\n className=\"w-full mt-2\"\n preload=\"metadata\"\n controls\n >\n <source src={audioPlaybackSrc} type={attachment.mimeType} />\n </audio>\n </div>\n );\n\n case 'video':\n return (\n <div className=\"relative rounded-lg overflow-hidden border bg-muted/20 max-w-lg\">\n <video\n src={attachment.dataUrl}\n poster={attachment.poster}\n controls\n className=\"w-full h-auto\"\n />\n {attachment.fileName && (\n <div className=\"absolute bottom-0 left-0 right-0 bg-black/50 text-white text-xs p-2\">\n {attachment.fileName}\n </div>\n )}\n </div>\n );\n\n default:\n return null;\n }\n});\n\n// Tool calls display component - memoized to prevent unnecessary re-renders\nconst ToolCallsDisplay: React.FC<{ toolCalls: ToolCall[]; label?: string }> = memo(function ToolCallsDisplay({ toolCalls, label }) {\n const [expandedCall, setExpandedCall] = useState<string | null>(null);\n\n const getStatusIcon = (status: ToolCall['status']) => {\n switch (status) {\n case 'pending':\n return <Clock className=\"h-3 w-3 text-muted-foreground\" />;\n case 'running':\n return <div className=\"h-3 w-3 border-2 border-primary border-t-transparent rounded-full animate-spin\" />;\n case 'completed':\n return <Check className=\"h-3 w-3 text-green-500\" />;\n case 'failed':\n return <X className=\"h-3 w-3 text-destructive\" />;\n }\n };\n\n const getStatusBadgeClasses = (status: ToolCall['status']) => {\n switch (status) {\n case 'pending':\n return 'bg-muted text-muted-foreground';\n case 'running':\n return 'bg-blue-100 text-blue-700 dark:bg-blue-900 dark:text-blue-300';\n case 'completed':\n return 'bg-green-100 text-green-700 dark:bg-green-900 dark:text-green-300';\n case 'failed':\n return 'bg-red-100 text-red-700 dark:bg-red-900 dark:text-red-300';\n }\n };\n\n return (\n <div className=\"space-y-2\">\n <div className=\"flex items-center gap-2 text-xs uppercase tracking-wide text-muted-foreground font-semibold\">\n <Wrench className=\"h-3 w-3\" />\n {label || 'Ferramenta utilizada'}\n </div>\n {toolCalls.map((call) => {\n const isExpanded = expandedCall === call.id;\n const ToggleIcon = isExpanded ? ChevronDown : ChevronRight;\n\n return (\n <Card key={call.id} className=\"border border-dashed border-primary/40 bg-card/60\">\n <button\n type=\"button\"\n className=\"flex w-full items-center justify-between gap-3 px-3 py-2 text-left\"\n onClick={() => setExpandedCall(isExpanded ? null : call.id)}\n >\n <div className=\"flex items-center gap-2\">\n {getStatusIcon(call.status)}\n <span className=\"font-medium text-sm\">{call.name}</span>\n <Badge variant=\"secondary\" className={getStatusBadgeClasses(call.status)}>\n {call.status}\n </Badge>\n </div>\n <ToggleIcon className=\"h-4 w-4 text-muted-foreground\" />\n </button>\n {isExpanded && (\n <CardContent className=\"pt-0 pb-3 px-3 text-xs space-y-2\">\n <div>\n <div className=\"font-medium text-muted-foreground mb-1\">Args</div>\n <pre className=\"rounded bg-muted p-2 overflow-x-auto text-xs\">\n {JSON.stringify(call.arguments, null, 2)}\n </pre>\n </div>\n {typeof call.result !== 'undefined' && (\n <div>\n <div className=\"font-medium text-muted-foreground mb-1\">Result</div>\n <pre className=\"rounded bg-muted p-2 overflow-x-auto text-xs\">\n {JSON.stringify(call.result, null, 2)}\n </pre>\n </div>\n )}\n {call.startTime && call.endTime && (\n <div className=\"text-muted-foreground\">\n Executed in {call.endTime - call.startTime}ms\n </div>\n )}\n </CardContent>\n )}\n </Card>\n );\n })}\n </div>\n );\n});\n\n// Keep memo comparison lightweight. Message objects are treated immutably by the\n// chat state, so reference equality is enough to detect actual message changes.\nconst arePropsEqual = (prevProps: MessageProps, nextProps: MessageProps): boolean => {\n if (prevProps.message !== nextProps.message) return false;\n \n // Compare other props\n if (prevProps.isUser !== nextProps.isUser) return false;\n if (prevProps.userAvatar !== nextProps.userAvatar) return false;\n if (prevProps.userName !== nextProps.userName) return false;\n if (prevProps.assistantName !== nextProps.assistantName) return false;\n if (prevProps.showTimestamp !== nextProps.showTimestamp) return false;\n if (prevProps.showAvatar !== nextProps.showAvatar) return false;\n if (prevProps.enableCopy !== nextProps.enableCopy) return false;\n if (prevProps.enableEdit !== nextProps.enableEdit) return false;\n if (prevProps.enableRegenerate !== nextProps.enableRegenerate) return false;\n if (prevProps.enableToolCallsDisplay !== nextProps.enableToolCallsDisplay) return false;\n if (prevProps.compactMode !== nextProps.compactMode) return false;\n if (prevProps.className !== nextProps.className) return false;\n if (prevProps.toolUsedLabel !== nextProps.toolUsedLabel) return false;\n if (prevProps.thinkingLabel !== nextProps.thinkingLabel) return false;\n if (prevProps.showMoreLabel !== nextProps.showMoreLabel) return false;\n if (prevProps.showLessLabel !== nextProps.showLessLabel) return false;\n if (prevProps.collapseLongMessages !== nextProps.collapseLongMessages) return false;\n if (prevProps.collapseLongMessagesForUserOnly !== nextProps.collapseLongMessagesForUserOnly) return false;\n if (prevProps.longMessagePreviewChars !== nextProps.longMessagePreviewChars) return false;\n if (prevProps.longMessageChunkChars !== nextProps.longMessageChunkChars) return false;\n if (prevProps.renderUserMarkdown !== nextProps.renderUserMarkdown) return false;\n if (prevProps.markdown !== nextProps.markdown) return false;\n if (prevProps.isExpanded !== nextProps.isExpanded) return false;\n if (prevProps.onToggleExpanded !== nextProps.onToggleExpanded) return false;\n if (prevProps.isGrouped !== nextProps.isGrouped) return false;\n if (prevProps.assistantAvatar !== nextProps.assistantAvatar) return false;\n \n return true;\n};\n\nexport const Message: React.FC<MessageProps> = memo(({\n message,\n isUser,\n userAvatar,\n userName = 'Você',\n assistantAvatar,\n assistantName = 'Assistente',\n showTimestamp = false,\n showAvatar = true,\n enableCopy = true,\n enableEdit = true,\n enableRegenerate = true,\n enableToolCallsDisplay = false,\n compactMode = false,\n onAction,\n className = '',\n toolUsedLabel,\n thinkingLabel = 'Thinking...',\n showMoreLabel = 'Show more',\n showLessLabel = 'Show less',\n collapseLongMessages = false,\n collapseLongMessagesForUserOnly = false,\n longMessagePreviewChars = 4000,\n longMessageChunkChars = 12000,\n renderUserMarkdown = true,\n markdown,\n isExpanded = false,\n onToggleExpanded,\n isGrouped = false,\n agentOptions = [],\n}) => {\n const [isEditing, setIsEditing] = useState(false);\n const [editContent, setEditContent] = useState(message.content);\n const [showActions, setShowActions] = useState(false);\n const [copied, setCopied] = useState(false);\n\n const messageIsUser = isUser ?? message.role === 'user';\n\n // Resolve multi-agent sender display\n const agentSender = !messageIsUser && message.senderAgentId\n ? agentOptions.find(a =>\n a.id === message.senderAgentId ||\n a.name.toLowerCase() === (message.senderAgentId ?? '').toLowerCase() ||\n a.name.toLowerCase() === (message.senderName ?? '').toLowerCase()\n )\n : undefined;\n const isMultiAgent = agentOptions.length > 1;\n const resolvedAssistantName = (isMultiAgent && (agentSender?.name || message.senderName)) || assistantName;\n const agentColor = agentSender ? (agentSender.color || getAgentColor(agentSender.id)) : undefined;\n const canEdit = enableEdit && messageIsUser;\n const canRegenerate = enableRegenerate && !messageIsUser;\n const normalizedPreviewChars = Math.max(longMessagePreviewChars, 1);\n const normalizedChunkChars = Math.max(longMessageChunkChars, 1);\n const previewOverride = typeof message.metadata?.previewContent === 'string'\n ? message.metadata.previewContent\n : undefined;\n const canCollapseMessage = collapseLongMessages\n && !message.isStreaming\n && message.content.length > normalizedPreviewChars\n && (!collapseLongMessagesForUserOnly || messageIsUser);\n const isCollapsed = canCollapseMessage && !isExpanded;\n const contentToRender = isCollapsed\n ? getCollapsedPreview(message.content, normalizedPreviewChars, previewOverride)\n : message.content;\n const shouldRenderMarkdown = !isCollapsed && (!messageIsUser || renderUserMarkdown);\n const shouldApplyLargeContentContainment = !isCollapsed && message.content.length > normalizedChunkChars;\n const contentStyle: React.CSSProperties | undefined = shouldApplyLargeContentContainment\n ? {\n contentVisibility: 'auto',\n containIntrinsicSize: '1px 400px',\n }\n : undefined;\n const horizontalOffsetClass = showAvatar\n ? messageIsUser\n ? (compactMode ? 'mr-9' : 'mr-11')\n : (compactMode ? 'ml-9' : 'ml-11')\n : '';\n\n const handleCopy = async () => {\n try {\n await navigator.clipboard.writeText(message.content);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n onAction?.({ action: 'copy', messageId: message.id, content: message.content });\n } catch (error) {\n console.error('Failed to copy message:', error);\n }\n };\n\n const handleEdit = () => {\n if (isEditing) {\n if (editContent.trim() !== message.content) {\n onAction?.({ action: 'edit', messageId: message.id, content: editContent.trim() });\n }\n setIsEditing(false);\n } else {\n setEditContent(message.content);\n setIsEditing(true);\n }\n };\n\n const handleCancelEdit = () => {\n setEditContent(message.content);\n setIsEditing(false);\n };\n\n const handleRegenerate = () => {\n onAction?.({ action: 'regenerate', messageId: message.id });\n };\n\n const handleToggleExpanded = () => {\n onToggleExpanded?.(message.id);\n };\n\n const formatTime = (timestamp: number) => {\n return new Date(timestamp).toLocaleTimeString('pt-BR', {\n hour: '2-digit',\n minute: '2-digit',\n });\n };\n\n return (\n <div\n className={`flex w-full flex-col ${className} max-w-[800px] mx-auto`}\n onMouseEnter={() => setShowActions(true)}\n onMouseLeave={() => setShowActions(false)}\n >\n\n {/* Header row with avatar and name - hidden when grouped */}\n {!isGrouped && (\n <div className={`flex gap-3 ${messageIsUser ? 'flex-row-reverse' : 'flex-row'} w-full mb-1`}>\n {/* Avatar */}\n {showAvatar && (\n <div className={`flex-shrink-0 ${compactMode ? 'mt-1' : 'mt-0'}`}>\n <Avatar className={compactMode ? 'h-6 w-6' : 'h-8 w-8'}>\n {messageIsUser ? (\n <>\n <AvatarImage src={userAvatar} alt={userName} />\n <AvatarFallback className=\"bg-primary text-primary-foreground\">\n {userName.charAt(0).toUpperCase()}\n </AvatarFallback>\n </>\n ) : agentSender ? (\n <>\n {agentSender.avatarUrl ? (\n <AvatarImage src={agentSender.avatarUrl} alt={agentSender.name} />\n ) : null}\n <AvatarFallback\n style={agentColor ? { backgroundColor: agentColor, color: 'white' } : undefined}\n className={agentColor ? 'text-[10px]' : 'bg-secondary text-secondary-foreground'}\n >\n {getAgentInitials(agentSender.name)}\n </AvatarFallback>\n </>\n ) : (\n <>\n {assistantAvatar || (\n <AvatarFallback className=\"bg-secondary text-secondary-foreground\">\n AI\n </AvatarFallback>\n )}\n </>\n )}\n </Avatar>\n </div>\n )}\n\n {/* Header */}\n <div className={`flex items-center gap-2 mb-1 ${messageIsUser ? 'flex-row-reverse' : 'flex-row'}`}>\n <span\n className={`font-medium ${compactMode ? 'text-sm' : 'text-base'}`}\n style={!messageIsUser && agentColor ? { color: agentColor } : undefined}\n >\n {messageIsUser ? userName : resolvedAssistantName}\n </span>\n {showTimestamp && (\n <span className=\"text-xs text-muted-foreground\">\n {formatTime(message.timestamp)}\n </span>\n )}\n {message.isEdited && (\n <Badge variant=\"outline\" className=\"text-xs\">\n editado\n </Badge>\n )}\n </div>\n </div>\n )}\n\n {/* Keep body alignment consistent across grouped and ungrouped messages */}\n <div className={`flex-1 min-w-0 ${messageIsUser ? 'text-right' : 'text-left'} ${horizontalOffsetClass}`}>\n\n {/* Message Body */}\n <div className={`relative inline-flex flex-col overflow-hidden text-left ${messageIsUser\n ? 'rounded-lg p-3 bg-primary text-primary-foreground ml-auto max-w-[85%]'\n : 'max-w-full'\n }`}>\n {isEditing ? (\n <div className=\"space-y-2\">\n <Textarea\n value={editContent}\n onChange={(e) => setEditContent(e.target.value)}\n className=\"min-h-[100px] resize-none\"\n autoFocus\n />\n <div className=\"flex gap-2 justify-end\">\n <Button variant=\"outline\" size=\"sm\" onClick={handleCancelEdit}>\n <X className=\"h-4 w-4 mr-1\" />\n Cancelar\n </Button>\n <Button size=\"sm\" onClick={handleEdit}>\n <Check className=\"h-4 w-4 mr-1\" />\n Salvar\n </Button>\n </div>\n </div>\n ) : (\n <>\n {/* Reasoning/Thinking Block */}\n {!messageIsUser && message.reasoning && (\n <ThinkingBlock\n reasoning={message.reasoning}\n isStreaming={message.isReasoningStreaming}\n label={thinkingLabel}\n />\n )}\n\n {/* Tool Calls */}\n {enableToolCallsDisplay && message.toolCalls && message.toolCalls.length > 0 && (\n <div className=\"mb-3\">\n <ToolCallsDisplay toolCalls={message.toolCalls} label={toolUsedLabel} />\n </div>\n )}\n\n <StreamingText\n content={contentToRender}\n isStreaming={message.isStreaming}\n thinkingLabel={thinkingLabel}\n renderMarkdown={shouldRenderMarkdown}\n markdown={markdown}\n plainTextChunkChars={normalizedChunkChars}\n contentStyle={contentStyle}\n hideThinkingIndicator={!!message.reasoning}\n />\n\n {canCollapseMessage && (\n <div className=\"mt-3\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-auto px-0 text-xs font-medium text-current hover:bg-transparent hover:opacity-80\"\n aria-expanded={!isCollapsed}\n onClick={handleToggleExpanded}\n >\n {isCollapsed ? showMoreLabel : showLessLabel}\n </Button>\n </div>\n )}\n\n {/* Attachments */}\n {message.attachments && message.attachments.length > 0 && (\n <div className=\"mt-3 space-y-2\">\n {message.attachments.map((attachment, index) => (\n <MediaRenderer key={index} attachment={attachment} />\n ))}\n </div>\n )}\n </>\n )}\n\n {/* Action Buttons */}\n {!isEditing && (showActions || copied) && (\n <div className={`absolute -top-2 flex gap-1 ${messageIsUser ? '-left-2' : '-right-2'\n }`}>\n {enableCopy && (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"secondary\"\n size=\"icon\"\n className=\"h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity\"\n onClick={handleCopy}\n >\n {copied ? (\n <Check className=\"h-3 w-3 text-green-500\" />\n ) : (\n <Copy className=\"h-3 w-3\" />\n )}\n </Button>\n </TooltipTrigger>\n <TooltipContent>\n {copied ? 'Copiado!' : 'Copiar'}\n </TooltipContent>\n </Tooltip>\n )}\n\n {canEdit && (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"secondary\"\n size=\"icon\"\n className=\"h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity\"\n onClick={handleEdit}\n >\n <Edit className=\"h-3 w-3\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>\n Editar\n </TooltipContent>\n </Tooltip>\n )}\n\n {canRegenerate && (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"secondary\"\n size=\"icon\"\n className=\"h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity\"\n onClick={handleRegenerate}\n >\n <RotateCcw className=\"h-3 w-3\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>\n Regenerar\n </TooltipContent>\n </Tooltip>\n )}\n </div>\n )}\n </div>\n </div>\n </div>\n );\n}, arePropsEqual);\n","import { ChatMessage, ChatThread, MediaAttachment, AgentOption } from '../types/chatTypes';\n\nexport const chatUtils = {\n generateId: (): string => \n (globalThis.crypto?.randomUUID?.() ?? `id-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`),\n\n generateMessageId: (): string => chatUtils.generateId(),\n generateThreadId: (): string => chatUtils.generateId(),\n \n createMessage: (\n role: 'user' | 'assistant' | 'system',\n content: string,\n attachments?: MediaAttachment[]\n ): ChatMessage => ({\n id: chatUtils.generateMessageId(),\n role,\n content,\n timestamp: Date.now(),\n attachments,\n isComplete: true,\n }),\n\n createThread: (title: string): ChatThread => ({\n id: chatUtils.generateThreadId(),\n title,\n createdAt: Date.now(),\n updatedAt: Date.now(),\n messageCount: 0,\n }),\n\n generateThreadTitle: (firstMessage: string): string => {\n const cleaned = firstMessage.replace(/[^\\w\\s]/g, '').trim();\n const words = cleaned.split(/\\s+/).slice(0, 6);\n return words.join(' ') || 'Nova Conversa';\n },\n};\n\n// ============================================================================\n// Multi-agent color/display utilities\n// ============================================================================\n\nconst AGENT_COLORS = [\n '#6366f1', // indigo\n '#8b5cf6', // violet\n '#ec4899', // pink\n '#f59e0b', // amber\n '#10b981', // emerald\n '#3b82f6', // blue\n '#ef4444', // red\n '#14b8a6', // teal\n '#f97316', // orange\n '#84cc16', // lime\n];\n\n/** Deterministic color for an agent based on its ID. */\nexport function getAgentColor(agentId: string): string {\n let hash = 0;\n for (let i = 0; i < agentId.length; i++) {\n hash = ((hash << 5) - hash + agentId.charCodeAt(i)) | 0;\n }\n return AGENT_COLORS[Math.abs(hash) % AGENT_COLORS.length];\n}\n\n/** Up to 2-letter initials from an agent name. */\nexport function getAgentInitials(name: string): string {\n const parts = name.trim().split(/\\s+/);\n if (parts.length >= 2) {\n return (parts[0][0] + parts[1][0]).toUpperCase();\n }\n return name.slice(0, 2).toUpperCase();\n}\n\n/** Assign colors to agents that don't have a custom color. Returns a new array. */\nexport function assignAgentColors(agents: AgentOption[]): (AgentOption & { color: string })[] {\n return agents.map((agent) => ({\n ...agent,\n color: agent.color || getAgentColor(agent.id),\n }));\n}\n\n","import * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"../../lib/utils\"\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n {\n variants: {\n variant: {\n default:\n \"bg-primary text-primary-foreground shadow-xs hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n outline:\n \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n secondary:\n \"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80\",\n ghost:\n \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n icon: \"size-9\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction Button({\n className,\n variant,\n size,\n asChild = false,\n ...props\n}: React.ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean\n }) {\n const Comp = asChild ? Slot : \"button\"\n\n return (\n <Comp\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n )\n}\n\nexport { Button, buttonVariants }\n","import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\nimport type { ChatConfig } from \"../types/chatTypes\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n\nexport const formatDate = (timestamp: number, labels?: ChatConfig['labels']) => {\n const date = new Date(timestamp);\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));\n\n if (diffDays === 0) {\n return labels?.today || 'Today';\n } else if (diffDays === 1) {\n return labels?.yesterday || 'Yesterday';\n } else if (diffDays < 7) {\n return `${diffDays} ${labels?.daysAgo || 'days ago'}`;\n } else {\n return date.toLocaleDateString('en-US', {\n day: '2-digit',\n month: 'short',\n });\n }\n};\n\nexport const createObjectUrlFromDataUrl = (dataUrl: string): string | null => {\n const match = dataUrl.match(/^data:(.+?);base64,(.+)$/s);\n if (!match) {\n return null;\n }\n\n try {\n const [, mimeType, base64] = match;\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n\n for (let i = 0; i < binary.length; i += 1) {\n bytes[i] = binary.charCodeAt(i);\n }\n\n const blob = new Blob([bytes], { type: mimeType || 'application/octet-stream' });\n return URL.createObjectURL(blob);\n } catch {\n return null;\n }\n};\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as AvatarPrimitive from \"@radix-ui/react-avatar\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Avatar({\n className,\n ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Root>) {\n return (\n <AvatarPrimitive.Root\n data-slot=\"avatar\"\n className={cn(\n \"relative flex size-8 shrink-0 overflow-hidden rounded-full\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction AvatarImage({\n className,\n ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Image>) {\n return (\n <AvatarPrimitive.Image\n data-slot=\"avatar-image\"\n className={cn(\"aspect-square size-full\", className)}\n {...props}\n />\n )\n}\n\nfunction AvatarFallback({\n className,\n ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {\n return (\n <AvatarPrimitive.Fallback\n data-slot=\"avatar-fallback\"\n className={cn(\n \"bg-muted flex size-full items-center justify-center rounded-full\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Avatar, AvatarImage, AvatarFallback }\n","import * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"../../lib/utils\"\n\nconst badgeVariants = cva(\n \"inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden\",\n {\n variants: {\n variant: {\n default:\n \"border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90\",\n secondary:\n \"border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90\",\n destructive:\n \"border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n outline:\n \"text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nfunction Badge({\n className,\n variant,\n asChild = false,\n ...props\n}: React.ComponentProps<\"span\"> &\n VariantProps<typeof badgeVariants> & { asChild?: boolean }) {\n const Comp = asChild ? Slot : \"span\"\n\n return (\n <Comp\n data-slot=\"badge\"\n className={cn(badgeVariants({ variant }), className)}\n {...props}\n />\n )\n}\n\nexport { Badge, badgeVariants }\n","import * as React from \"react\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Card({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card\"\n className={cn(\n \"bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-header\"\n className={cn(\n \"@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-title\"\n className={cn(\"leading-none font-semibold\", className)}\n {...props}\n />\n )\n}\n\nfunction CardDescription({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-description\"\n className={cn(\"text-muted-foreground text-sm\", className)}\n {...props}\n />\n )\n}\n\nfunction CardAction({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-action\"\n className={cn(\n \"col-start-2 row-span-2 row-start-1 self-start justify-self-end\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-content\"\n className={cn(\"px-6\", className)}\n {...props}\n />\n )\n}\n\nfunction CardFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-footer\"\n className={cn(\"flex items-center px-6 [.border-t]:pt-6\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Card,\n CardHeader,\n CardFooter,\n CardTitle,\n CardAction,\n CardDescription,\n CardContent,\n}\n","import * as React from \"react\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Textarea({ className, ...props }: React.ComponentProps<\"textarea\">) {\n return (\n <textarea\n data-slot=\"textarea\"\n className={cn(\n \"border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Textarea }\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as TooltipPrimitive from \"@radix-ui/react-tooltip\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction TooltipProvider({\n delayDuration = 0,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {\n return (\n <TooltipPrimitive.Provider\n data-slot=\"tooltip-provider\"\n delayDuration={delayDuration}\n {...props}\n />\n )\n}\n\nfunction Tooltip({\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Root>) {\n return (\n <TooltipProvider>\n <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n </TooltipProvider>\n )\n}\n\nfunction TooltipTrigger({\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />\n}\n\nfunction TooltipContent({\n className,\n sideOffset = 0,\n children,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Content>) {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n data-slot=\"tooltip-content\"\n sideOffset={sideOffset}\n className={cn(\n \"bg-primary text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance\",\n className\n )}\n {...props}\n >\n {children}\n <TooltipPrimitive.Arrow className=\"bg-primary fill-primary z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]\" />\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n )\n}\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }\n","import React, { useState, useRef, useEffect } from 'react';\nimport { ChatThread } from '../../types/chatTypes';\nimport { Button } from '../ui/button';\nimport { Input } from '../ui/input';\nimport {\n Sidebar as ShadcnSidebar,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarHeader,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarRail,\n useSidebar,\n} from '../ui/sidebar';\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from '../ui/dialog';\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from '../ui/alert-dialog';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '../ui/dropdown-menu';\nimport {\n Plus,\n MoreHorizontal,\n Edit2,\n Trash2,\n Archive,\n Search,\n Filter,\n Bot,\n} from 'lucide-react';\nimport { UserMenu, UserMenuUser, UserMenuCallbacks, UserMenuConfig } from './UserMenu';\nimport { Avatar, AvatarFallback } from '../ui/avatar';\n\nexport interface SidebarConfig {\n labels?: {\n newChat?: string;\n search?: string;\n customComponentLabel?: string;\n showArchived?: string;\n hideArchived?: string;\n noThreadsFound?: string;\n noThreadsYet?: string;\n deleteConfirmTitle?: string;\n deleteConfirmDescription?: string;\n renameThread?: string;\n archiveThread?: string;\n unarchiveThread?: string;\n deleteThread?: string;\n today?: string;\n yesterday?: string;\n createNewThread?: string;\n threadNamePlaceholder?: string;\n cancel?: string;\n create?: string;\n daysAgo?: string;\n };\n branding?: {\n logo?: React.ReactNode;\n title?: React.ReactNode;\n subtitle?: React.ReactNode;\n };\n userMenu?: UserMenuConfig;\n}\n\nexport interface SidebarProps extends React.ComponentProps<typeof ShadcnSidebar> {\n threads: ChatThread[];\n currentThreadId?: string | null;\n config: SidebarConfig;\n onCreateThread?: (title?: string) => void;\n onSelectThread?: (threadId: string) => void;\n onRenameThread?: (threadId: string, newTitle: string) => void;\n onDeleteThread?: (threadId: string) => void;\n onArchiveThread?: (threadId: string) => void;\n // User menu props\n user?: UserMenuUser | null;\n userMenuCallbacks?: UserMenuCallbacks;\n currentTheme?: 'light' | 'dark' | 'system';\n showThemeOptions?: boolean;\n /** Additional items to render in the user menu */\n userMenuAdditionalItems?: React.ReactNode;\n}\n\n// Create thread dialog\nconst CreateThreadDialog: React.FC<{\n config: SidebarConfig;\n onCreateThread: (title?: string) => void;\n trigger?: React.ReactNode;\n}> = ({ config, onCreateThread, trigger }) => {\n const [title, setTitle] = useState('');\n const [isOpen, setIsOpen] = useState(false);\n\n const handleCreate = () => {\n onCreateThread(title.trim() || undefined);\n setTitle('');\n setIsOpen(false);\n };\n\n return (\n <Dialog open={isOpen} onOpenChange={setIsOpen}>\n <DialogTrigger asChild>\n {trigger || (\n <Button className=\"w-full justify-start\" variant=\"outline\">\n <Plus className=\"mr-2 h-4 w-4\" />\n {config.labels?.newChat || 'New Chat'}\n </Button>\n )}\n </DialogTrigger>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>{config.labels?.createNewThread || 'New Conversation'}</DialogTitle>\n <DialogDescription>\n Give your new conversation a name or leave blank to auto-generate one.\n </DialogDescription>\n </DialogHeader>\n <Input\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n placeholder={config.labels?.threadNamePlaceholder || \"Conversation name\"}\n onKeyDown={(e) => e.key === 'Enter' && handleCreate()}\n autoFocus\n />\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => setIsOpen(false)}>\n {config.labels?.cancel || 'Cancel'}\n </Button>\n <Button onClick={handleCreate}>\n {config.labels?.create || 'Create'}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n};\n\nconst ThreadInitialsIcon = ({ title }: { title: string }) => {\n const initials = title\n ?.split(' ')\n .map((n) => n[0])\n .slice(0, 2)\n .join('')\n .toUpperCase() || '?';\n \n return (\n <div className=\"flex shrink-0 items-center justify-center rounded bg-muted text-[10px] font-medium\">\n {initials}\n </div>\n );\n};\n\nexport const Sidebar: React.FC<SidebarProps> = ({\n threads,\n currentThreadId,\n config,\n onCreateThread,\n onSelectThread,\n onRenameThread,\n onDeleteThread,\n onArchiveThread,\n // User menu props\n user,\n userMenuCallbacks,\n currentTheme,\n showThemeOptions = true,\n userMenuAdditionalItems,\n ...props\n}) => {\n const [searchQuery, setSearchQuery] = useState('');\n const [showArchived, setShowArchived] = useState(false);\n const [deleteThreadId, setDeleteThreadId] = useState<string | null>(null);\n const [editingThreadId, setEditingThreadId] = useState<string | null>(null);\n const [editTitle, setEditTitle] = useState('');\n const inputRef = useRef<HTMLInputElement>(null);\n \n // Use the sidebar context to control expansion\n const { setOpen } = useSidebar();\n\n useEffect(() => {\n if (editingThreadId && inputRef.current) {\n inputRef.current.focus();\n inputRef.current.select();\n }\n }, [editingThreadId]);\n\n // Filter threads based on search and archive filter\n const filteredThreads = threads.filter(thread => {\n const title = (thread.title ?? '').toString();\n const matchesSearch = title.toLowerCase().includes(searchQuery.toLowerCase());\n const matchesArchiveFilter = showArchived || !thread.isArchived;\n return matchesSearch && matchesArchiveFilter;\n });\n\n // Group threads by date\n const groupedThreads = filteredThreads.reduce((groups, thread) => {\n const date = new Date(thread.updatedAt);\n const today = new Date();\n const yesterday = new Date(today.getTime() - 24 * 60 * 60 * 1000);\n\n let groupKey: string;\n if (date.toDateString() === today.toDateString()) {\n groupKey = config.labels?.today || 'Today';\n } else if (date.toDateString() === yesterday.toDateString()) {\n groupKey = config.labels?.yesterday || 'Yesterday';\n } else {\n groupKey = date.toLocaleDateString('en-US', {\n weekday: 'long',\n day: '2-digit',\n month: 'long',\n });\n }\n\n if (!groups[groupKey]) {\n groups[groupKey] = [];\n }\n groups[groupKey].push(thread);\n return groups;\n }, {} as Record<string, ChatThread[]>);\n\n const handleDeleteThread = (threadId: string) => {\n onDeleteThread?.(threadId);\n setDeleteThreadId(null);\n };\n\n const startEditing = (thread: ChatThread) => {\n setEditingThreadId(thread.id);\n setEditTitle(thread.title || '');\n };\n\n const saveEdit = () => {\n if (editingThreadId && editTitle.trim()) {\n onRenameThread?.(editingThreadId, editTitle.trim());\n }\n setEditingThreadId(null);\n };\n\n const cancelEdit = () => {\n setEditingThreadId(null);\n };\n\n return (\n <ShadcnSidebar collapsible=\"icon\" {...props}>\n <SidebarHeader>\n {/* Branding / Logo */}\n <div className=\"flex items-center gap-3 px-2 py-3\">\n <div className=\"flex items-center justify-center shrink-0\">\n {config.branding?.logo || (\n <Avatar className=\"h-8 w-8\">\n <AvatarFallback className=\"bg-primary text-primary-foreground\">\n <Bot className=\"h-4 w-4\" />\n </AvatarFallback>\n </Avatar>\n )}\n </div>\n <div className=\"flex flex-col min-w-0 group-data-[collapsible=icon]:hidden\">\n <span className=\"text-sm font-semibold truncate\">\n {config.branding?.title || 'Chat'}\n </span>\n {config.branding?.subtitle && (\n <span className=\"text-xs text-muted-foreground truncate\">\n {config.branding.subtitle}\n </span>\n )}\n </div>\n </div>\n\n {/* New Chat Button */}\n {onCreateThread && (\n <CreateThreadDialog \n config={config} \n onCreateThread={onCreateThread} \n trigger={\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton\n size=\"lg\"\n className=\"w-full justify-start gap-2 border border-sidebar-border shadow-sm hover:bg-sidebar-accent hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:justify-center\"\n tooltip={config.labels?.newChat || 'New Chat'}\n >\n <Plus className=\"size-4\" />\n <span className=\"group-data-[collapsible=icon]:hidden\">{config.labels?.newChat || 'New Chat'}</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n }\n />\n )}\n \n {/* Search */}\n <div className=\"px-2 py-1 mt-4\">\n {/* Expanded View: Input */}\n <div className=\"relative group-data-[collapsible=icon]:hidden\">\n <Search className=\"pointer-events-none absolute left-2 top-1/2 size-4 -translate-y-1/2 select-none opacity-50\" />\n <Input\n className=\"pl-8 h-8 bg-sidebar-accent/50 border-sidebar-border focus-visible:ring-1 focus-visible:ring-sidebar-ring\"\n placeholder={config.labels?.search || \"Search...\"}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n />\n </div>\n \n {/* Collapsed View: Search Icon Button (expands sidebar on click) */}\n <div className=\"hidden group-data-[collapsible=icon]:flex justify-center\">\n <Button \n variant=\"ghost\" \n size=\"icon\" \n className=\"h-7 w-7\" \n onClick={() => setOpen(true)}\n title={config.labels?.search || \"Search\"}\n >\n <Search className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n </SidebarHeader>\n\n <SidebarContent>\n {/* Archive Filter Toggle (if needed) */}\n {threads.some(t => t.isArchived) && (\n <div className=\"px-4 py-2 mt-2 group-data-[collapsible=icon]:hidden\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setShowArchived(!showArchived)}\n className=\"h-6 text-xs w-full justify-start text-muted-foreground\"\n >\n <Filter className=\"mr-2 h-3 w-3\" />\n {showArchived ? \n (config.labels?.hideArchived || 'Hide Archived') : \n (config.labels?.showArchived || 'Show Archived')\n }\n </Button>\n </div>\n )}\n\n {Object.keys(groupedThreads).length === 0 ? (\n <div className=\"px-4 py-8 text-center text-muted-foreground group-data-[collapsible=icon]:hidden\">\n <div className=\"mx-auto h-8 w-8 mb-2 flex items-center justify-center rounded-full bg-muted/50\">\n <Plus className=\"h-4 w-4 opacity-50\" />\n </div>\n <p className=\"text-xs\">\n {searchQuery ? \n (config.labels?.noThreadsFound || 'No conversations found') : \n (config.labels?.noThreadsYet || 'No conversations yet')\n }\n </p>\n </div>\n ) : (\n Object.entries(groupedThreads).map(([group, groupThreads]) => (\n <SidebarGroup className=\"mt-2\" key={group}>\n <SidebarGroupLabel className=\"group-data-[collapsible=icon]:hidden\">{group}</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu>\n {groupThreads.map((thread) => (\n <SidebarMenuItem key={thread.id}>\n {editingThreadId === thread.id ? (\n <div className=\"flex items-center gap-1 px-2 py-1\">\n <Input\n ref={inputRef}\n value={editTitle}\n onChange={(e) => setEditTitle(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') saveEdit();\n if (e.key === 'Escape') cancelEdit();\n }}\n onBlur={saveEdit}\n className=\"h-7 text-sm\"\n />\n </div>\n ) : (\n <SidebarMenuButton\n isActive={currentThreadId === thread.id}\n onClick={() => onSelectThread?.(thread.id)}\n tooltip={thread.title}\n >\n <ThreadInitialsIcon title={thread.title || '?'} />\n <div className=\"flex flex-col items-start gap-0.5 flex-1 min-w-0 group-data-[collapsible=icon]:hidden\">\n <span className=\"truncate w-full\">{thread.title || 'New Chat'}</span>\n </div>\n {thread.isArchived && <Archive className=\"ml-auto h-3 w-3 opacity-50 group-data-[collapsible=icon]:hidden\" />}\n </SidebarMenuButton>\n )}\n \n {!editingThreadId && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <SidebarMenuAction showOnHover>\n <MoreHorizontal />\n <span className=\"sr-only\">More</span>\n </SidebarMenuAction>\n </DropdownMenuTrigger>\n <DropdownMenuContent className=\"w-48\" side=\"right\" align=\"start\">\n <DropdownMenuItem onClick={() => startEditing(thread)}>\n <Edit2 className=\"mr-2 h-4 w-4\" />\n <span>{config.labels?.renameThread || 'Rename'}</span>\n </DropdownMenuItem>\n <DropdownMenuItem onClick={() => onArchiveThread?.(thread.id)}>\n <Archive className=\"mr-2 h-4 w-4\" />\n <span>\n {thread.isArchived ? \n (config.labels?.unarchiveThread || 'Unarchive') : \n (config.labels?.archiveThread || 'Archive')\n }\n </span>\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem \n onClick={() => setDeleteThreadId(thread.id)}\n className=\"text-destructive focus:text-destructive\"\n >\n <Trash2 className=\"mr-2 h-4 w-4\" />\n <span>{config.labels?.deleteThread || 'Delete'}</span>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n </SidebarMenuItem>\n ))}\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n ))\n )}\n </SidebarContent>\n \n <SidebarFooter>\n <UserMenu\n user={user}\n config={config.userMenu}\n callbacks={userMenuCallbacks}\n currentTheme={currentTheme}\n showThemeOptions={showThemeOptions}\n additionalItems={userMenuAdditionalItems}\n />\n </SidebarFooter>\n \n <SidebarRail />\n\n {/* Delete confirmation dialog - only render when needed to avoid Radix focus conflicts */}\n {deleteThreadId && (\n <AlertDialog open={!!deleteThreadId} onOpenChange={() => setDeleteThreadId(null)}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>{config.labels?.deleteConfirmTitle || 'Delete Conversation'}</AlertDialogTitle>\n <AlertDialogDescription>\n {config.labels?.deleteConfirmDescription ||\n 'Are you sure you want to delete this conversation? This action cannot be undone.'\n }\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>{config.labels?.cancel || 'Cancel'}</AlertDialogCancel>\n <AlertDialogAction\n onClick={() => deleteThreadId && handleDeleteThread(deleteThreadId)}\n className=\"bg-destructive text-destructive-foreground hover:bg-destructive/90\"\n >\n {config.labels?.deleteThread || 'Delete'}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n )}\n </ShadcnSidebar>\n );\n};\n","import * as React from \"react\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Input({ className, type, ...props }: React.ComponentProps<\"input\">) {\n return (\n <input\n type={type}\n data-slot=\"input\"\n className={cn(\n \"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm\",\n \"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]\",\n \"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Input }\n","import * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, VariantProps } from \"class-variance-authority\"\nimport { PanelLeftIcon } from \"lucide-react\"\n\nimport { useIsMobile } from \"../../hooks/use-mobile\"\nimport { cn } from \"../../lib/utils\"\nimport { Button } from \"./button\"\nimport { Input } from \"./input\"\nimport { Separator } from \"./separator\"\nimport {\n Sheet,\n SheetContent,\n SheetDescription,\n SheetHeader,\n SheetTitle,\n} from \"./sheet\"\nimport { Skeleton } from \"./skeleton\"\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"./tooltip\"\n\nconst SIDEBAR_COOKIE_NAME = \"sidebar_state\"\nconst SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7\nconst SIDEBAR_WIDTH = \"16rem\"\nconst SIDEBAR_WIDTH_MOBILE = \"18rem\"\nconst SIDEBAR_WIDTH_ICON = \"3rem\"\nconst SIDEBAR_KEYBOARD_SHORTCUT = \"b\"\n\ntype SidebarContextProps = {\n state: \"expanded\" | \"collapsed\"\n open: boolean\n setOpen: (open: boolean) => void\n openMobile: boolean\n setOpenMobile: (open: boolean) => void\n isMobile: boolean\n toggleSidebar: () => void\n}\n\nconst SidebarContext = React.createContext<SidebarContextProps | null>(null)\n\nfunction useSidebar() {\n const context = React.useContext(SidebarContext)\n if (!context) {\n throw new Error(\"useSidebar must be used within a SidebarProvider.\")\n }\n\n return context\n}\n\nfunction SidebarProvider({\n defaultOpen = true,\n open: openProp,\n onOpenChange: setOpenProp,\n className,\n style,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & {\n defaultOpen?: boolean\n open?: boolean\n onOpenChange?: (open: boolean) => void\n}) {\n const isMobile = useIsMobile()\n const [openMobile, setOpenMobile] = React.useState(false)\n\n // This is the internal state of the sidebar.\n // We use openProp and setOpenProp for control from outside the component.\n const [_open, _setOpen] = React.useState(defaultOpen)\n const open = openProp ?? _open\n const setOpen = React.useCallback(\n (value: boolean | ((value: boolean) => boolean)) => {\n const openState = typeof value === \"function\" ? value(open) : value\n if (setOpenProp) {\n setOpenProp(openState)\n } else {\n _setOpen(openState)\n }\n\n // This sets the cookie to keep the sidebar state.\n document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`\n },\n [setOpenProp, open]\n )\n\n // Helper to toggle the sidebar.\n const toggleSidebar = React.useCallback(() => {\n return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open)\n }, [isMobile, setOpen, setOpenMobile])\n\n // Adds a keyboard shortcut to toggle the sidebar.\n React.useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (\n event.key === SIDEBAR_KEYBOARD_SHORTCUT &&\n (event.metaKey || event.ctrlKey)\n ) {\n event.preventDefault()\n toggleSidebar()\n }\n }\n\n window.addEventListener(\"keydown\", handleKeyDown)\n return () => window.removeEventListener(\"keydown\", handleKeyDown)\n }, [toggleSidebar])\n\n // We add a state so that we can do data-state=\"expanded\" or \"collapsed\".\n // This makes it easier to style the sidebar with Tailwind classes.\n const state = open ? \"expanded\" : \"collapsed\"\n\n const contextValue = React.useMemo<SidebarContextProps>(\n () => ({\n state,\n open,\n setOpen,\n isMobile,\n openMobile,\n setOpenMobile,\n toggleSidebar,\n }),\n [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar]\n )\n\n return (\n <SidebarContext.Provider value={contextValue}>\n <TooltipProvider delayDuration={0}>\n <div\n data-slot=\"sidebar-wrapper\"\n style={\n {\n \"--sidebar-width\": SIDEBAR_WIDTH,\n \"--sidebar-width-icon\": SIDEBAR_WIDTH_ICON,\n ...style,\n } as React.CSSProperties\n }\n className={cn(\n \"group/sidebar-wrapper has-data-[variant=inset]:bg-sidebar flex min-h-svh w-full\",\n className\n )}\n {...props}\n >\n {children}\n </div>\n </TooltipProvider>\n </SidebarContext.Provider>\n )\n}\n\nfunction Sidebar({\n side = \"left\",\n variant = \"sidebar\",\n collapsible = \"offcanvas\",\n className,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & {\n side?: \"left\" | \"right\"\n variant?: \"sidebar\" | \"floating\" | \"inset\"\n collapsible?: \"offcanvas\" | \"icon\" | \"none\"\n}) {\n \n const { isMobile, state, openMobile, setOpenMobile } = useSidebar()\n\n if (collapsible === \"none\") {\n return (\n <div\n data-slot=\"sidebar\"\n className={cn(\n \"bg-sidebar text-sidebar-foreground flex h-full w-(--sidebar-width) flex-col\",\n className\n )}\n {...props}\n >\n {children}\n </div>\n )\n }\n\n if (isMobile) {\n return (\n <Sheet open={openMobile} onOpenChange={setOpenMobile} {...props}>\n <SheetContent\n data-sidebar=\"sidebar\"\n data-slot=\"sidebar\"\n data-mobile=\"true\"\n className=\"bg-sidebar text-sidebar-foreground w-(--sidebar-width) p-0 [&>button]:hidden\"\n style={\n {\n \"--sidebar-width\": SIDEBAR_WIDTH_MOBILE,\n } as React.CSSProperties\n }\n side={side}\n >\n <SheetHeader className=\"sr-only\">\n <SheetTitle>Sidebar</SheetTitle>\n <SheetDescription>Displays the mobile sidebar.</SheetDescription>\n </SheetHeader>\n <div className=\"flex h-full w-full flex-col\">{children}</div>\n </SheetContent>\n </Sheet>\n )\n }\n\n return (\n <div\n className=\"group peer text-sidebar-foreground hidden md:block\"\n data-state={state}\n data-collapsible={state === \"collapsed\" ? collapsible : \"\"}\n data-variant={variant}\n data-side={side}\n data-slot=\"sidebar\"\n >\n {/* This is what handles the sidebar gap on desktop */}\n <div\n data-slot=\"sidebar-gap\"\n className={cn(\n \"relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear\",\n \"group-data-[collapsible=offcanvas]:w-0\",\n \"group-data-[side=right]:rotate-180\",\n variant === \"floating\" || variant === \"inset\"\n ? \"group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]\"\n : \"group-data-[collapsible=icon]:w-(--sidebar-width-icon)\"\n )}\n />\n <div\n data-slot=\"sidebar-container\"\n className={cn(\n \"fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:flex\",\n side === \"left\"\n ? \"left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]\"\n : \"right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]\",\n // Adjust the padding for floating and inset variants.\n variant === \"floating\" || variant === \"inset\"\n ? \"p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]\"\n : \"group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l\",\n className\n )}\n {...props}\n >\n <div\n data-sidebar=\"sidebar\"\n data-slot=\"sidebar-inner\"\n className=\"bg-sidebar group-data-[variant=floating]:border-sidebar-border flex h-full w-full flex-col group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:shadow-sm\"\n >\n {children}\n </div>\n </div>\n </div>\n )\n}\n\nfunction SidebarTrigger({\n className,\n onClick,\n ...props\n}: React.ComponentProps<typeof Button>) {\n const { toggleSidebar } = useSidebar()\n\n return (\n <Button\n data-sidebar=\"trigger\"\n data-slot=\"sidebar-trigger\"\n variant=\"ghost\"\n size=\"icon\"\n className={cn(\"size-7\", className)}\n onClick={(event) => {\n onClick?.(event)\n toggleSidebar()\n }}\n {...props}\n >\n <PanelLeftIcon />\n <span className=\"sr-only\">Toggle Sidebar</span>\n </Button>\n )\n}\n\nfunction SidebarRail({ className, ...props }: React.ComponentProps<\"button\">) {\n const { toggleSidebar } = useSidebar()\n\n return (\n <button\n data-sidebar=\"rail\"\n data-slot=\"sidebar-rail\"\n aria-label=\"Toggle Sidebar\"\n tabIndex={-1}\n onClick={toggleSidebar}\n title=\"Toggle Sidebar\"\n className={cn(\n \"hover:after:bg-sidebar-border absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] sm:flex\",\n \"in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize\",\n \"[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize\",\n \"hover:group-data-[collapsible=offcanvas]:bg-sidebar group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full\",\n \"[[data-side=left][data-collapsible=offcanvas]_&]:-right-2\",\n \"[[data-side=right][data-collapsible=offcanvas]_&]:-left-2\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarInset({ className, ...props }: React.ComponentProps<\"main\">) {\n return (\n <main\n data-slot=\"sidebar-inset\"\n className={cn(\n \"bg-background relative flex w-full flex-1 flex-col\",\n \"md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarInput({\n className,\n ...props\n}: React.ComponentProps<typeof Input>) {\n return (\n <Input\n data-slot=\"sidebar-input\"\n data-sidebar=\"input\"\n className={cn(\"bg-background h-8 w-full shadow-none\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-header\"\n data-sidebar=\"header\"\n className={cn(\"flex flex-col gap-2 p-2\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-footer\"\n data-sidebar=\"footer\"\n className={cn(\"flex flex-col gap-2 p-2\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof Separator>) {\n return (\n <Separator\n data-slot=\"sidebar-separator\"\n data-sidebar=\"separator\"\n className={cn(\"bg-sidebar-border mx-2 w-auto\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-content\"\n data-sidebar=\"content\"\n className={cn(\n \"flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-group\"\n data-sidebar=\"group\"\n className={cn(\"relative flex w-full min-w-0 flex-col p-2\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarGroupLabel({\n className,\n asChild = false,\n ...props\n}: React.ComponentProps<\"div\"> & { asChild?: boolean }) {\n const Comp = asChild ? Slot : \"div\"\n\n return (\n <Comp\n data-slot=\"sidebar-group-label\"\n data-sidebar=\"group-label\"\n className={cn(\n \"text-sidebar-foreground/70 ring-sidebar-ring flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium outline-hidden transition-[margin,opacity] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0\",\n \"group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarGroupAction({\n className,\n asChild = false,\n ...props\n}: React.ComponentProps<\"button\"> & { asChild?: boolean }) {\n const Comp = asChild ? Slot : \"button\"\n\n return (\n <Comp\n data-slot=\"sidebar-group-action\"\n data-sidebar=\"group-action\"\n className={cn(\n \"text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0\",\n // Increases the hit area of the button on mobile.\n \"after:absolute after:-inset-2 md:after:hidden\",\n \"group-data-[collapsible=icon]:hidden\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarGroupContent({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-group-content\"\n data-sidebar=\"group-content\"\n className={cn(\"w-full text-sm\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarMenu({ className, ...props }: React.ComponentProps<\"ul\">) {\n return (\n <ul\n data-slot=\"sidebar-menu\"\n data-sidebar=\"menu\"\n className={cn(\"flex w-full min-w-0 flex-col gap-1\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuItem({ className, ...props }: React.ComponentProps<\"li\">) {\n return (\n <li\n data-slot=\"sidebar-menu-item\"\n data-sidebar=\"menu-item\"\n className={cn(\"group/menu-item relative\", className)}\n {...props}\n />\n )\n}\n\nconst sidebarMenuButtonVariants = cva(\n \"peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-hidden ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0\",\n {\n variants: {\n variant: {\n default: \"hover:bg-sidebar-accent hover:text-sidebar-accent-foreground\",\n outline:\n \"bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]\",\n },\n size: {\n default: \"h-8 text-sm\",\n sm: \"h-7 text-xs\",\n lg: \"h-12 text-sm group-data-[collapsible=icon]:p-0!\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction SidebarMenuButton({\n asChild = false,\n isActive = false,\n variant = \"default\",\n size = \"default\",\n tooltip,\n className,\n ...props\n}: React.ComponentProps<\"button\"> & {\n asChild?: boolean\n isActive?: boolean\n tooltip?: string | React.ComponentProps<typeof TooltipContent>\n} & VariantProps<typeof sidebarMenuButtonVariants>) {\n const Comp = asChild ? Slot : \"button\"\n const { isMobile, state } = useSidebar()\n\n const button = (\n <Comp\n data-slot=\"sidebar-menu-button\"\n data-sidebar=\"menu-button\"\n data-size={size}\n data-active={isActive}\n className={cn(sidebarMenuButtonVariants({ variant, size }), className)}\n {...props}\n />\n )\n\n if (!tooltip) {\n return button\n }\n\n if (typeof tooltip === \"string\") {\n tooltip = {\n children: tooltip,\n }\n }\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>{button}</TooltipTrigger>\n <TooltipContent\n side=\"right\"\n align=\"center\"\n hidden={state !== \"collapsed\" || isMobile}\n {...tooltip}\n />\n </Tooltip>\n )\n}\n\nfunction SidebarMenuAction({\n className,\n asChild = false,\n showOnHover = false,\n ...props\n}: React.ComponentProps<\"button\"> & {\n asChild?: boolean\n showOnHover?: boolean\n}) {\n const Comp = asChild ? Slot : \"button\"\n\n return (\n <Comp\n data-slot=\"sidebar-menu-action\"\n data-sidebar=\"menu-action\"\n className={cn(\n \"text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground peer-hover/menu-button:text-sidebar-accent-foreground absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0\",\n // Increases the hit area of the button on mobile.\n \"after:absolute after:-inset-2 md:after:hidden\",\n \"peer-data-[size=sm]/menu-button:top-1\",\n \"peer-data-[size=default]/menu-button:top-1.5\",\n \"peer-data-[size=lg]/menu-button:top-2.5\",\n \"group-data-[collapsible=icon]:hidden\",\n showOnHover &&\n \"peer-data-[active=true]/menu-button:text-sidebar-accent-foreground group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 md:opacity-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuBadge({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-menu-badge\"\n data-sidebar=\"menu-badge\"\n className={cn(\n \"text-sidebar-foreground pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums select-none\",\n \"peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground\",\n \"peer-data-[size=sm]/menu-button:top-1\",\n \"peer-data-[size=default]/menu-button:top-1.5\",\n \"peer-data-[size=lg]/menu-button:top-2.5\",\n \"group-data-[collapsible=icon]:hidden\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuSkeleton({\n className,\n showIcon = false,\n ...props\n}: React.ComponentProps<\"div\"> & {\n showIcon?: boolean\n}) {\n // Random width between 50 to 90%.\n const width = React.useMemo(() => {\n return `${Math.floor(Math.random() * 40) + 50}%`\n }, [])\n\n return (\n <div\n data-slot=\"sidebar-menu-skeleton\"\n data-sidebar=\"menu-skeleton\"\n className={cn(\"flex h-8 items-center gap-2 rounded-md px-2\", className)}\n {...props}\n >\n {showIcon && (\n <Skeleton\n className=\"size-4 rounded-md\"\n data-sidebar=\"menu-skeleton-icon\"\n />\n )}\n <Skeleton\n className=\"h-4 max-w-(--skeleton-width) flex-1\"\n data-sidebar=\"menu-skeleton-text\"\n style={\n {\n \"--skeleton-width\": width,\n } as React.CSSProperties\n }\n />\n </div>\n )\n}\n\nfunction SidebarMenuSub({ className, ...props }: React.ComponentProps<\"ul\">) {\n return (\n <ul\n data-slot=\"sidebar-menu-sub\"\n data-sidebar=\"menu-sub\"\n className={cn(\n \"border-sidebar-border mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l px-2.5 py-0.5\",\n \"group-data-[collapsible=icon]:hidden\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuSubItem({\n className,\n ...props\n}: React.ComponentProps<\"li\">) {\n return (\n <li\n data-slot=\"sidebar-menu-sub-item\"\n data-sidebar=\"menu-sub-item\"\n className={cn(\"group/menu-sub-item relative\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuSubButton({\n asChild = false,\n size = \"md\",\n isActive = false,\n className,\n ...props\n}: React.ComponentProps<\"a\"> & {\n asChild?: boolean\n size?: \"sm\" | \"md\"\n isActive?: boolean\n}) {\n const Comp = asChild ? Slot : \"a\"\n\n return (\n <Comp\n data-slot=\"sidebar-menu-sub-button\"\n data-sidebar=\"menu-sub-button\"\n data-size={size}\n data-active={isActive}\n className={cn(\n \"text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground [&>svg]:text-sidebar-accent-foreground flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 outline-hidden focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0\",\n \"data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground\",\n size === \"sm\" && \"text-xs\",\n size === \"md\" && \"text-sm\",\n \"group-data-[collapsible=icon]:hidden\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupAction,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarHeader,\n SidebarInput,\n SidebarInset,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuBadge,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSkeleton,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n SidebarProvider,\n SidebarRail,\n SidebarSeparator,\n SidebarTrigger,\n useSidebar,\n}\n","import * as React from \"react\"\n\nconst MOBILE_BREAKPOINT = 768\n\nexport function useIsMobile() {\n const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined)\n\n React.useEffect(() => {\n const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)\n const onChange = () => {\n setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)\n }\n mql.addEventListener(\"change\", onChange)\n setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)\n return () => mql.removeEventListener(\"change\", onChange)\n }, [])\n\n return !!isMobile\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as SeparatorPrimitive from \"@radix-ui/react-separator\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Separator({\n className,\n orientation = \"horizontal\",\n decorative = true,\n ...props\n}: React.ComponentProps<typeof SeparatorPrimitive.Root>) {\n return (\n <SeparatorPrimitive.Root\n data-slot=\"separator\"\n decorative={decorative}\n orientation={orientation}\n className={cn(\n \"bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Separator }\n","import * as React from \"react\"\nimport * as SheetPrimitive from \"@radix-ui/react-dialog\"\nimport { XIcon } from \"lucide-react\"\n\nimport { cn } from \"../../lib/utils\"\n\n/**\n * Clean up body styles that Radix may leave behind.\n * This fixes an issue where pointer-events: none gets stuck on body.\n */\nfunction cleanupBodyStyles() {\n if (typeof document !== 'undefined' && document.body.style.pointerEvents === 'none') {\n document.body.style.pointerEvents = '';\n }\n}\n\nfunction Sheet({ open, onOpenChange, ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {\n // Track previous open state to detect close transition\n const prevOpenRef = React.useRef(open);\n\n React.useEffect(() => {\n // When transitioning from open to closed, ensure cleanup after animation\n if (prevOpenRef.current === true && open === false) {\n const timeout = setTimeout(cleanupBodyStyles, 350); // After close animation (300ms + buffer)\n return () => clearTimeout(timeout);\n }\n prevOpenRef.current = open;\n }, [open]);\n\n // Cleanup on unmount\n React.useEffect(() => {\n return () => {\n cleanupBodyStyles();\n };\n }, []);\n\n return <SheetPrimitive.Root data-slot=\"sheet\" open={open} onOpenChange={onOpenChange} {...props} />\n}\n\nfunction SheetTrigger({\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Trigger>) {\n return <SheetPrimitive.Trigger data-slot=\"sheet-trigger\" {...props} />\n}\n\nfunction SheetClose({\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Close>) {\n return <SheetPrimitive.Close data-slot=\"sheet-close\" {...props} />\n}\n\nfunction SheetPortal({\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Portal>) {\n return <SheetPrimitive.Portal data-slot=\"sheet-portal\" {...props} />\n}\n\nfunction SheetOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Overlay>) {\n return (\n <SheetPrimitive.Overlay\n data-slot=\"sheet-overlay\"\n className={cn(\n \"fixed inset-0 z-50 bg-black/50\",\n \"data-[state=open]:animate-in data-[state=closed]:animate-out\",\n \"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n \"data-[state=closed]:pointer-events-none\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SheetContent({\n className,\n children,\n side = \"right\",\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Content> & {\n side?: \"top\" | \"right\" | \"bottom\" | \"left\"\n}) {\n return (\n <SheetPortal>\n <SheetOverlay />\n <SheetPrimitive.Content\n data-slot=\"sheet-content\"\n aria-describedby={undefined}\n className={cn(\n \"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500\",\n side === \"right\" &&\n \"data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm\",\n side === \"left\" &&\n \"data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm\",\n side === \"top\" &&\n \"data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b\",\n side === \"bottom\" &&\n \"data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 h-auto border-t\",\n className\n )}\n {...props}\n >\n {children}\n <SheetPrimitive.Close className=\"ring-offset-background focus:ring-ring data-[state=open]:bg-secondary absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none\">\n <XIcon className=\"size-4\" />\n <span className=\"sr-only\">Close</span>\n </SheetPrimitive.Close>\n </SheetPrimitive.Content>\n </SheetPortal>\n )\n}\n\nfunction SheetHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sheet-header\"\n className={cn(\"flex flex-col gap-1.5 p-4\", className)}\n {...props}\n />\n )\n}\n\nfunction SheetFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sheet-footer\"\n className={cn(\"mt-auto flex flex-col gap-2 p-4\", className)}\n {...props}\n />\n )\n}\n\nfunction SheetTitle({\n className,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Title>) {\n return (\n <SheetPrimitive.Title\n data-slot=\"sheet-title\"\n className={cn(\"text-foreground font-semibold\", className)}\n {...props}\n />\n )\n}\n\nfunction SheetDescription({\n className,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Description>) {\n return (\n <SheetPrimitive.Description\n data-slot=\"sheet-description\"\n className={cn(\"text-muted-foreground text-sm\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Sheet,\n SheetTrigger,\n SheetClose,\n SheetContent,\n SheetHeader,\n SheetFooter,\n SheetTitle,\n SheetDescription,\n}\n","import { cn } from \"../../lib/utils\"\n\nfunction Skeleton({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"skeleton\"\n className={cn(\"bg-accent animate-pulse rounded-md\", className)}\n {...props}\n />\n )\n}\n\nexport { Skeleton }\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as DialogPrimitive from \"@radix-ui/react-dialog\"\nimport { XIcon } from \"lucide-react\"\n\nimport { cn } from \"../../lib/utils\"\n\n/**\n * Clean up body styles that Radix may leave behind.\n * This fixes an issue where pointer-events: none gets stuck on body.\n */\nfunction cleanupBodyStyles() {\n if (typeof document !== 'undefined' && document.body.style.pointerEvents === 'none') {\n document.body.style.pointerEvents = '';\n }\n}\n\nfunction Dialog({\n open,\n onOpenChange,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Root>) {\n // Track previous open state to detect close transition\n const prevOpenRef = React.useRef(open);\n\n React.useEffect(() => {\n // When transitioning from open to closed, ensure cleanup after animation\n if (prevOpenRef.current === true && open === false) {\n const timeout = setTimeout(cleanupBodyStyles, 250); // After close animation (200ms + buffer)\n return () => clearTimeout(timeout);\n }\n prevOpenRef.current = open;\n }, [open]);\n\n // Cleanup on unmount\n React.useEffect(() => {\n return () => {\n cleanupBodyStyles();\n };\n }, []);\n\n return <DialogPrimitive.Root data-slot=\"dialog\" open={open} onOpenChange={onOpenChange} {...props} />\n}\n\nfunction DialogTrigger({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {\n return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />\n}\n\nfunction DialogPortal({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Portal>) {\n return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />\n}\n\nfunction DialogClose({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Close>) {\n return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />\n}\n\nfunction DialogOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {\n return (\n <DialogPrimitive.Overlay\n data-slot=\"dialog-overlay\"\n className={cn(\n \"fixed inset-0 z-50 bg-black/50\",\n \"data-[state=open]:animate-in data-[state=closed]:animate-out\",\n \"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n \"data-[state=closed]:pointer-events-none\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DialogContent({\n className,\n children,\n showCloseButton = true,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Content> & {\n showCloseButton?: boolean\n}) {\n return (\n <DialogPortal data-slot=\"dialog-portal\">\n <DialogOverlay />\n <DialogPrimitive.Content\n data-slot=\"dialog-content\"\n aria-describedby={undefined}\n className={cn(\n \"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg\",\n className\n )}\n {...props}\n >\n {children}\n {showCloseButton && (\n <DialogPrimitive.Close\n data-slot=\"dialog-close\"\n className=\"ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\"\n >\n <XIcon />\n <span className=\"sr-only\">Close</span>\n </DialogPrimitive.Close>\n )}\n </DialogPrimitive.Content>\n </DialogPortal>\n )\n}\n\nfunction DialogHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dialog-header\"\n className={cn(\"flex flex-col gap-2 text-center sm:text-left\", className)}\n {...props}\n />\n )\n}\n\nfunction DialogFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dialog-footer\"\n className={cn(\n \"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DialogTitle({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Title>) {\n return (\n <DialogPrimitive.Title\n data-slot=\"dialog-title\"\n className={cn(\"text-lg leading-none font-semibold\", className)}\n {...props}\n />\n )\n}\n\nfunction DialogDescription({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Description>) {\n return (\n <DialogPrimitive.Description\n data-slot=\"dialog-description\"\n className={cn(\"text-muted-foreground text-sm\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as AlertDialogPrimitive from \"@radix-ui/react-alert-dialog\"\n\nimport { cn } from \"../../lib/utils\"\nimport { buttonVariants } from \"./button\"\n\n/**\n * Clean up body styles that Radix may leave behind.\n * This fixes an issue where pointer-events: none gets stuck on body.\n */\nfunction cleanupBodyStyles() {\n if (typeof document !== 'undefined' && document.body.style.pointerEvents === 'none') {\n document.body.style.pointerEvents = '';\n }\n}\n\nfunction AlertDialog({\n open,\n onOpenChange,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Root>) {\n // Track previous open state to detect close transition\n const prevOpenRef = React.useRef(open);\n\n React.useEffect(() => {\n // When transitioning from open to closed, ensure cleanup after animation\n if (prevOpenRef.current === true && open === false) {\n const timeout = setTimeout(cleanupBodyStyles, 250); // After close animation (200ms + buffer)\n return () => clearTimeout(timeout);\n }\n prevOpenRef.current = open;\n }, [open]);\n\n // Cleanup on unmount\n React.useEffect(() => {\n return () => {\n cleanupBodyStyles();\n };\n }, []);\n\n return <AlertDialogPrimitive.Root data-slot=\"alert-dialog\" open={open} onOpenChange={onOpenChange} {...props} />\n}\n\nfunction AlertDialogTrigger({\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Trigger>) {\n return (\n <AlertDialogPrimitive.Trigger data-slot=\"alert-dialog-trigger\" {...props} />\n )\n}\n\nfunction AlertDialogPortal({\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Portal>) {\n return (\n <AlertDialogPrimitive.Portal data-slot=\"alert-dialog-portal\" {...props} />\n )\n}\n\nfunction AlertDialogOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Overlay>) {\n return (\n <AlertDialogPrimitive.Overlay\n data-slot=\"alert-dialog-overlay\"\n className={cn(\n \"fixed inset-0 z-50 bg-black/50\",\n \"data-[state=open]:animate-in data-[state=closed]:animate-out\",\n \"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n \"data-[state=closed]:pointer-events-none\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction AlertDialogContent({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Content>) {\n return (\n <AlertDialogPortal>\n <AlertDialogOverlay />\n <AlertDialogPrimitive.Content\n data-slot=\"alert-dialog-content\"\n className={cn(\n \"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg\",\n className\n )}\n {...props}\n />\n </AlertDialogPortal>\n )\n}\n\nfunction AlertDialogHeader({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"alert-dialog-header\"\n className={cn(\"flex flex-col gap-2 text-center sm:text-left\", className)}\n {...props}\n />\n )\n}\n\nfunction AlertDialogFooter({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"alert-dialog-footer\"\n className={cn(\n \"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction AlertDialogTitle({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Title>) {\n return (\n <AlertDialogPrimitive.Title\n data-slot=\"alert-dialog-title\"\n className={cn(\"text-lg font-semibold\", className)}\n {...props}\n />\n )\n}\n\nfunction AlertDialogDescription({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Description>) {\n return (\n <AlertDialogPrimitive.Description\n data-slot=\"alert-dialog-description\"\n className={cn(\"text-muted-foreground text-sm\", className)}\n {...props}\n />\n )\n}\n\nfunction AlertDialogAction({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Action>) {\n return (\n <AlertDialogPrimitive.Action\n className={cn(buttonVariants(), className)}\n {...props}\n />\n )\n}\n\nfunction AlertDialogCancel({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Cancel>) {\n return (\n <AlertDialogPrimitive.Cancel\n className={cn(buttonVariants({ variant: \"outline\" }), className)}\n {...props}\n />\n )\n}\n\nexport {\n AlertDialog,\n AlertDialogPortal,\n AlertDialogOverlay,\n AlertDialogTrigger,\n AlertDialogContent,\n AlertDialogHeader,\n AlertDialogFooter,\n AlertDialogTitle,\n AlertDialogDescription,\n AlertDialogAction,\n AlertDialogCancel,\n}\n","import * as React from \"react\"\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\"\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from \"lucide-react\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction DropdownMenu({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {\n return <DropdownMenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />\n}\n\nfunction DropdownMenuPortal({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {\n return (\n <DropdownMenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />\n )\n}\n\nfunction DropdownMenuTrigger({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {\n return (\n <DropdownMenuPrimitive.Trigger\n data-slot=\"dropdown-menu-trigger\"\n {...props}\n />\n )\n}\n\nfunction DropdownMenuContent({\n className,\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {\n return (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n data-slot=\"dropdown-menu-content\"\n sideOffset={sideOffset}\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md\",\n className\n )}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n )\n}\n\nfunction DropdownMenuGroup({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {\n return (\n <DropdownMenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />\n )\n}\n\nfunction DropdownMenuItem({\n className,\n inset,\n variant = \"default\",\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean\n variant?: \"default\" | \"destructive\"\n}) {\n return (\n <DropdownMenuPrimitive.Item\n data-slot=\"dropdown-menu-item\"\n data-inset={inset}\n data-variant={variant}\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuCheckboxItem({\n className,\n children,\n checked,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {\n return (\n <DropdownMenuPrimitive.CheckboxItem\n data-slot=\"dropdown-menu-checkbox-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n checked={checked}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n )\n}\n\nfunction DropdownMenuRadioGroup({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {\n return (\n <DropdownMenuPrimitive.RadioGroup\n data-slot=\"dropdown-menu-radio-group\"\n {...props}\n />\n )\n}\n\nfunction DropdownMenuRadioItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {\n return (\n <DropdownMenuPrimitive.RadioItem\n data-slot=\"dropdown-menu-radio-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <CircleIcon className=\"size-2 fill-current\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n )\n}\n\nfunction DropdownMenuLabel({\n className,\n inset,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {\n inset?: boolean\n}) {\n return (\n <DropdownMenuPrimitive.Label\n data-slot=\"dropdown-menu-label\"\n data-inset={inset}\n className={cn(\n \"px-2 py-1.5 text-sm font-medium data-[inset]:pl-8\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n return (\n <DropdownMenuPrimitive.Separator\n data-slot=\"dropdown-menu-separator\"\n className={cn(\"bg-border -mx-1 my-1 h-px\", className)}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuShortcut({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"dropdown-menu-shortcut\"\n className={cn(\n \"text-muted-foreground ml-auto text-xs tracking-widest\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuSub({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {\n return <DropdownMenuPrimitive.Sub data-slot=\"dropdown-menu-sub\" {...props} />\n}\n\nfunction DropdownMenuSubTrigger({\n className,\n inset,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {\n inset?: boolean\n}) {\n return (\n <DropdownMenuPrimitive.SubTrigger\n data-slot=\"dropdown-menu-sub-trigger\"\n data-inset={inset}\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8\",\n className\n )}\n {...props}\n >\n {children}\n <ChevronRightIcon className=\"ml-auto size-4\" />\n </DropdownMenuPrimitive.SubTrigger>\n )\n}\n\nfunction DropdownMenuSubContent({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {\n return (\n <DropdownMenuPrimitive.SubContent\n data-slot=\"dropdown-menu-sub-content\"\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport {\n DropdownMenu,\n DropdownMenuPortal,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuLabel,\n DropdownMenuItem,\n DropdownMenuCheckboxItem,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubTrigger,\n DropdownMenuSubContent,\n}\n","import React from 'react';\nimport {\n SidebarMenu,\n SidebarMenuItem,\n SidebarMenuButton,\n useSidebar,\n} from '../ui/sidebar';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n DropdownMenuLabel,\n} from '../ui/dropdown-menu';\nimport { Avatar, AvatarFallback, AvatarImage } from '../ui/avatar';\nimport {\n User,\n Settings,\n LogOut,\n ChevronsUpDown,\n Moon,\n Sun,\n Palette,\n} from 'lucide-react';\n\nexport interface UserMenuConfig {\n labels?: {\n profile?: string;\n settings?: string;\n theme?: string;\n lightMode?: string;\n darkMode?: string;\n systemTheme?: string;\n logout?: string;\n guest?: string;\n };\n}\n\nexport interface UserMenuUser {\n id: string;\n name?: string;\n email?: string;\n avatar?: string;\n}\n\nexport interface UserMenuCallbacks {\n onViewProfile?: () => void;\n onOpenSettings?: () => void;\n onThemeChange?: (theme: 'light' | 'dark' | 'system') => void;\n onLogout?: () => void;\n}\n\nexport interface UserMenuProps {\n user?: UserMenuUser | null;\n config?: UserMenuConfig;\n callbacks?: UserMenuCallbacks;\n currentTheme?: 'light' | 'dark' | 'system';\n /** Show theme options in the menu */\n showThemeOptions?: boolean;\n /** Additional menu items to render */\n additionalItems?: React.ReactNode;\n}\n\n// Get initials from name or email\nconst getInitials = (name?: string, email?: string): string => {\n if (name) {\n return name\n .split(' ')\n .map((n) => n[0])\n .slice(0, 2)\n .join('')\n .toUpperCase();\n }\n if (email) {\n return email[0].toUpperCase();\n }\n return 'U';\n};\n\n// Get display name\nconst getDisplayName = (user?: UserMenuUser | null, guestLabel?: string): string => {\n if (!user) return guestLabel || 'Guest';\n return user.name || user.email?.split('@')[0] || guestLabel || 'Guest';\n};\n\nexport const UserMenu: React.FC<UserMenuProps> = ({\n user,\n config,\n callbacks,\n currentTheme = 'system',\n showThemeOptions = true,\n additionalItems,\n}) => {\n const { isMobile } = useSidebar();\n\n const labels = {\n profile: config?.labels?.profile || 'Profile',\n settings: config?.labels?.settings || 'Settings',\n theme: config?.labels?.theme || 'Theme',\n lightMode: config?.labels?.lightMode || 'Light',\n darkMode: config?.labels?.darkMode || 'Dark',\n systemTheme: config?.labels?.systemTheme || 'System',\n logout: config?.labels?.logout || 'Log out',\n guest: config?.labels?.guest || 'Guest',\n };\n\n const displayName = getDisplayName(user, labels.guest);\n const initials = getInitials(user?.name, user?.email);\n\n return (\n <SidebarMenu>\n <SidebarMenuItem>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <SidebarMenuButton\n size=\"lg\"\n className=\"data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground\"\n tooltip={displayName}\n >\n <Avatar className=\"h-8 w-8 rounded-lg\">\n {user?.avatar && <AvatarImage src={user.avatar} alt={displayName} />}\n <AvatarFallback className=\"rounded-lg bg-primary/10 text-primary text-xs font-medium\">\n {initials}\n </AvatarFallback>\n </Avatar>\n <div className=\"grid flex-1 text-left text-sm leading-tight group-data-[collapsible=icon]:hidden\">\n <span className=\"truncate font-medium\">{displayName}</span>\n {user?.email && (\n <span className=\"truncate text-xs text-muted-foreground\">\n {user.email}\n </span>\n )}\n </div>\n <ChevronsUpDown className=\"ml-auto size-4 group-data-[collapsible=icon]:hidden\" />\n </SidebarMenuButton>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n className=\"w-[--radix-dropdown-menu-trigger-width] min-w-56 rounded-lg\"\n side={isMobile ? 'bottom' : 'right'}\n align=\"end\"\n sideOffset={4}\n >\n <DropdownMenuLabel className=\"p-0 font-normal\">\n <div className=\"flex items-center gap-2 px-1 py-1.5 text-left text-sm\">\n <Avatar className=\"h-8 w-8 rounded-lg\">\n {user?.avatar && <AvatarImage src={user.avatar} alt={displayName} />}\n <AvatarFallback className=\"rounded-lg bg-primary/10 text-primary text-xs font-medium\">\n {initials}\n </AvatarFallback>\n </Avatar>\n <div className=\"grid flex-1 text-left text-sm leading-tight\">\n <span className=\"truncate font-medium\">{displayName}</span>\n {user?.email && (\n <span className=\"truncate text-xs text-muted-foreground\">\n {user.email}\n </span>\n )}\n </div>\n </div>\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n \n {/* Profile */}\n {callbacks?.onViewProfile && (\n <DropdownMenuItem onClick={callbacks.onViewProfile}>\n <User className=\"mr-2 h-4 w-4\" />\n <span>{labels.profile}</span>\n </DropdownMenuItem>\n )}\n\n {/* Settings */}\n {callbacks?.onOpenSettings && (\n <DropdownMenuItem onClick={callbacks.onOpenSettings}>\n <Settings className=\"mr-2 h-4 w-4\" />\n <span>{labels.settings}</span>\n </DropdownMenuItem>\n )}\n\n {/* Additional items */}\n {additionalItems}\n\n {/* Theme options */}\n {showThemeOptions && callbacks?.onThemeChange && (\n <>\n <DropdownMenuSeparator />\n <DropdownMenuItem \n onClick={() => callbacks.onThemeChange?.('light')}\n className={currentTheme === 'light' ? 'bg-accent' : ''}\n >\n <Sun className=\"mr-2 h-4 w-4\" />\n <span>{labels.lightMode}</span>\n </DropdownMenuItem>\n <DropdownMenuItem \n onClick={() => callbacks.onThemeChange?.('dark')}\n className={currentTheme === 'dark' ? 'bg-accent' : ''}\n >\n <Moon className=\"mr-2 h-4 w-4\" />\n <span>{labels.darkMode}</span>\n </DropdownMenuItem>\n <DropdownMenuItem \n onClick={() => callbacks.onThemeChange?.('system')}\n className={currentTheme === 'system' ? 'bg-accent' : ''}\n >\n <Palette className=\"mr-2 h-4 w-4\" />\n <span>{labels.systemTheme}</span>\n </DropdownMenuItem>\n </>\n )}\n\n {/* Logout */}\n {callbacks?.onLogout && (\n <>\n <DropdownMenuSeparator />\n <DropdownMenuItem \n onClick={callbacks.onLogout}\n className=\"text-destructive focus:text-destructive focus:bg-destructive/10\"\n >\n <LogOut className=\"mr-2 h-4 w-4\" />\n <span>{labels.logout}</span>\n </DropdownMenuItem>\n </>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n </SidebarMenu>\n );\n};\n\nexport default UserMenu;\n","import React from 'react';\nimport { Card, CardHeader } from '../ui/card';\nimport { Button } from '../ui/button';\nimport { Avatar, AvatarFallback, AvatarImage } from '../ui/avatar';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '../ui/tooltip';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '../ui/dropdown-menu';\nimport {\n Bot,\n MoreVertical,\n Download,\n Upload,\n Trash2,\n Plus,\n Menu,\n Moon,\n Sun,\n ChevronDown,\n Check,\n} from 'lucide-react';\nimport { ReactNode } from 'react';\nimport { SidebarTrigger } from '../ui/sidebar';\nimport type { AgentOption } from '../../types/chatTypes';\nimport { ParticipantsSelector } from './AgentSelectors';\n\nexport interface ChatHeaderConfig {\n branding?: {\n logo?: ReactNode;\n title?: string;\n subtitle?: string;\n };\n agentSelector?: {\n enabled?: boolean;\n label?: string;\n hideIfSingle?: boolean;\n };\n labels?: {\n newThread?: string;\n exportData?: string;\n importData?: string;\n clearAll?: string;\n sidebarToggle?: string;\n customComponentToggle?: string;\n settings?: string;\n toggleDarkMode?: string;\n lightMode?: string;\n darkMode?: string;\n };\n customComponent?: {\n label?: string;\n icon?: ReactNode;\n onClick?: () => void;\n };\n /** Additional actions to render in the header (before the settings menu) */\n headerActions?: ReactNode;\n}\n\nexport interface ChatHeaderProps {\n config: ChatHeaderConfig;\n currentThreadTitle?: string | null;\n onSidebarToggle?: () => void;\n onCustomComponentToggle?: () => void;\n onNewThread?: () => void;\n onExportData?: () => void;\n onImportData?: (file: File) => void;\n onClearAll?: () => void;\n showCustomComponentButton?: boolean;\n isMobile?: boolean;\n showAgentSelector?: boolean;\n isMultiAgentMode?: boolean;\n agentOptions?: AgentOption[];\n selectedAgentId?: string | null;\n onSelectAgent?: (agentId: string) => void;\n participantIds?: string[];\n onParticipantsChange?: (ids: string[]) => void;\n className?: string;\n}\n\nexport const ChatHeader: React.FC<ChatHeaderProps> = ({\n config,\n currentThreadTitle,\n onSidebarToggle: _onSidebarToggle,\n onCustomComponentToggle,\n onNewThread,\n onExportData,\n onImportData,\n onClearAll,\n showCustomComponentButton,\n isMobile,\n showAgentSelector = false,\n isMultiAgentMode = false,\n agentOptions = [],\n selectedAgentId = null,\n onSelectAgent,\n participantIds,\n onParticipantsChange,\n className = '',\n}) => {\n const [isDarkMode, setIsDarkMode] = React.useState(() => {\n if (typeof window === 'undefined') return false;\n return document.documentElement.classList.contains('dark');\n });\n\n React.useEffect(() => {\n const observer = new MutationObserver(() => {\n setIsDarkMode(document.documentElement.classList.contains('dark'));\n });\n\n observer.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['class'],\n });\n\n // Listen for system theme changes\n const mediaQuery = globalThis.matchMedia('(prefers-color-scheme: dark)');\n const handleSystemThemeChange = (e: MediaQueryListEvent) => {\n const savedTheme = localStorage.getItem('theme');\n if (!savedTheme) {\n // Only update if user hasn't set an explicit preference\n setIsDarkMode(e.matches);\n }\n };\n\n mediaQuery.addEventListener('change', handleSystemThemeChange);\n\n return () => {\n observer.disconnect();\n mediaQuery.removeEventListener('change', handleSystemThemeChange);\n };\n }, []);\n\n const toggleDarkMode = () => {\n const isDark = document.documentElement.classList.contains('dark');\n if (isDark) {\n document.documentElement.classList.remove('dark');\n localStorage.setItem('theme', 'light');\n } else {\n document.documentElement.classList.add('dark');\n localStorage.setItem('theme', 'dark');\n }\n setIsDarkMode(!isDark);\n };\n\n\n const handleImportClick = () => {\n const input = document.createElement('input');\n input.type = 'file';\n input.accept = '.json';\n input.onchange = (e) => {\n const file = (e.target as HTMLInputElement).files?.[0];\n if (file && onImportData) {\n onImportData(file);\n }\n };\n input.click();\n };\n\n const selectedAgent = agentOptions.find((agent) => agent.id === selectedAgentId) || null;\n const agentPlaceholder = config.agentSelector?.label || 'Select agent';\n\n return (\n <Card\n data-chat-header\n className={`py-0 border-b rounded-none relative z-10 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/80 ${className}`}\n style={isMobile ? { paddingTop: 'env(safe-area-inset-top)' } : undefined}\n >\n <CardHeader className=\"p-2\">\n <div className=\"flex items-center justify-between gap-2\">\n {/* Left side - Sidebar toggle + Agent Selector */}\n <div className=\"flex items-center gap-1\">\n <Tooltip>\n <TooltipTrigger asChild>\n <SidebarTrigger className=\"-ml-1\" />\n </TooltipTrigger>\n <TooltipContent>\n {config.labels?.sidebarToggle || 'Toggle Sidebar'}\n </TooltipContent>\n </Tooltip>\n\n {/* Agent Selector */}\n {showAgentSelector && isMultiAgentMode && onParticipantsChange && (\n <ParticipantsSelector\n agents={agentOptions}\n participantIds={participantIds ?? agentOptions.map(a => a.id)}\n onParticipantsChange={onParticipantsChange}\n />\n )}\n {showAgentSelector && !isMultiAgentMode && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n className=\"h-9 px-3 gap-1.5 font-medium text-base hover:bg-accent/50\"\n >\n {selectedAgent?.avatarUrl ? (\n <Avatar className=\"h-5 w-5\">\n <AvatarImage src={selectedAgent.avatarUrl} alt={selectedAgent.name} />\n <AvatarFallback className=\"text-[10px]\">\n {selectedAgent.name.charAt(0).toUpperCase()}\n </AvatarFallback>\n </Avatar>\n ) : null}\n <span className=\"max-w-[200px] truncate\">\n {selectedAgent?.name || agentPlaceholder}\n </span>\n <ChevronDown className=\"h-4 w-4 opacity-50\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"w-[280px]\">\n {agentOptions.map((agent) => {\n const isSelected = agent.id === selectedAgentId;\n return (\n <DropdownMenuItem\n key={agent.id}\n onClick={() => onSelectAgent?.(agent.id)}\n className=\"flex items-start gap-3 p-3 cursor-pointer\"\n >\n {agent.avatarUrl ? (\n <Avatar className=\"h-6 w-6 mt-0.5 shrink-0\">\n <AvatarImage src={agent.avatarUrl} alt={agent.name} />\n <AvatarFallback className=\"text-[10px]\">\n {agent.name.charAt(0).toUpperCase()}\n </AvatarFallback>\n </Avatar>\n ) : (\n <div className=\"h-6 w-6 mt-0.5 shrink-0 flex items-center justify-center rounded-full bg-primary/10\">\n <Bot className=\"h-3.5 w-3.5 text-primary\" />\n </div>\n )}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium text-sm\">{agent.name}</span>\n {isSelected && (\n <Check className=\"h-4 w-4 text-primary shrink-0\" />\n )}\n </div>\n {agent.description && (\n <p className=\"text-xs text-muted-foreground mt-0.5 line-clamp-2\">\n {agent.description}\n </p>\n )}\n </div>\n </DropdownMenuItem>\n );\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n\n {/* Mobile title when no agent selector */}\n {!showAgentSelector && isMobile && (\n <span className=\"text-sm font-medium truncate max-w-[150px] ml-2\">\n {currentThreadTitle || config.branding?.title || 'Chat'}\n </span>\n )}\n </div>\n\n {/* Spacer */}\n <div className=\"flex-1\" />\n\n {/* Right side - Custom component button + Settings menu */}\n <div className=\"flex items-center gap-1\">\n {/* Custom component toggle button (desktop + mobile) */}\n {showCustomComponentButton && config.customComponent && (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={onCustomComponentToggle}\n >\n {config.customComponent.icon || <Menu className=\"h-4 w-4\" />}\n </Button>\n </TooltipTrigger>\n <TooltipContent>\n {config.customComponent.label || config.labels?.customComponentToggle || 'Toggle'}\n </TooltipContent>\n </Tooltip>\n )}\n\n {/* Custom header actions (passed from parent) */}\n {config.headerActions}\n\n {/* Settings dropdown menu */}\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"ghost\" size=\"icon\" className=\"h-8 w-8\">\n <MoreVertical className=\"h-4 w-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {onNewThread && (\n <>\n <DropdownMenuItem onClick={() => onNewThread?.()} className=\"font-medium text-primary\">\n <Plus className=\"h-4 w-4 mr-2\" />\n {config.labels?.newThread || 'New Thread'}\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n </>\n )}\n\n {onExportData && (\n <DropdownMenuItem onClick={onExportData}>\n <Download className=\"h-4 w-4 mr-2\" />\n {config.labels?.exportData || 'Export Data'}\n </DropdownMenuItem>\n )}\n\n {onImportData && (\n <DropdownMenuItem onClick={handleImportClick}>\n <Upload className=\"h-4 w-4 mr-2\" />\n {config.labels?.importData || 'Import Data'}\n </DropdownMenuItem>\n )}\n\n {(onExportData || onImportData) && (\n <DropdownMenuSeparator />\n )}\n\n <DropdownMenuItem onClick={toggleDarkMode}>\n {isDarkMode ? (\n <>\n <Sun className=\"h-4 w-4 mr-2\" />\n {config.labels?.lightMode || 'Light Mode'}\n </>\n ) : (\n <>\n <Moon className=\"h-4 w-4 mr-2\" />\n {config.labels?.darkMode || 'Dark Mode'}\n </>\n )}\n </DropdownMenuItem>\n\n {onClearAll && (\n <>\n <DropdownMenuSeparator />\n <DropdownMenuItem\n onClick={onClearAll}\n className=\"text-destructive\"\n >\n <Trash2 className=\"h-4 w-4 mr-2\" />\n {config.labels?.clearAll || 'Clear All'}\n </DropdownMenuItem>\n </>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n </div>\n </CardHeader>\n </Card>\n );\n};\n","import React, { memo, useMemo } from 'react';\nimport { Check, ChevronDown, Users, AtSign, X } from 'lucide-react';\nimport { AgentOption } from '../../types/chatTypes';\nimport { Button } from '../ui/button';\nimport { Avatar, AvatarFallback, AvatarImage } from '../ui/avatar';\nimport { Badge } from '../ui/badge';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n DropdownMenuSeparator,\n DropdownMenuLabel,\n} from '../ui/dropdown-menu';\nimport { getAgentColor, getAgentInitials, assignAgentColors } from '../../lib/chatUtils';\n\ninterface ParticipantsSelectorProps {\n /** All available agents */\n agents: AgentOption[];\n /** Currently selected participant IDs */\n participantIds: string[];\n /** Callback when participants change */\n onParticipantsChange: (ids: string[]) => void;\n /** Label for the selector */\n label?: string;\n /** Maximum participants to show in collapsed view */\n maxVisible?: number;\n /** Disabled state */\n disabled?: boolean;\n}\n\n/**\n * Multi-select dropdown for choosing which agents participate in the conversation.\n */\nexport const ParticipantsSelector: React.FC<ParticipantsSelectorProps> = memo(({\n agents,\n participantIds,\n onParticipantsChange,\n label = 'Team',\n maxVisible = 3,\n disabled = false,\n}) => {\n // Assign colors to agents that don't have them\n const agentsWithColors = useMemo(() => assignAgentColors(agents), [agents]);\n \n // Get selected agents\n const selectedAgents = useMemo(() => \n agentsWithColors.filter(a => participantIds.includes(a.id)),\n [agentsWithColors, participantIds]\n );\n \n const toggleParticipant = (agentId: string) => {\n if (participantIds.includes(agentId)) {\n // Don't allow removing the last participant\n if (participantIds.length > 1) {\n onParticipantsChange(participantIds.filter(id => id !== agentId));\n }\n } else {\n onParticipantsChange([...participantIds, agentId]);\n }\n };\n \n const selectAll = () => {\n onParticipantsChange(agentsWithColors.map(a => a.id));\n };\n \n const visibleAgents = selectedAgents.slice(0, maxVisible);\n const hiddenCount = selectedAgents.length - maxVisible;\n \n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n className=\"h-9 px-2 gap-1.5 text-sm hover:bg-accent/50\"\n disabled={disabled}\n >\n <Users className=\"h-4 w-4 text-muted-foreground\" />\n <div className=\"flex items-center gap-1\">\n {visibleAgents.length > 0 ? (\n <>\n <div className=\"flex -space-x-1.5\">\n {visibleAgents.map(agent => (\n <Avatar key={agent.id} className=\"h-5 w-5 border-2 border-background\">\n <AvatarImage src={agent.avatarUrl} alt={agent.name} />\n <AvatarFallback\n style={{ backgroundColor: agent.color || getAgentColor(agent.id), color: 'white' }}\n className=\"text-[8px]\"\n >\n {getAgentInitials(agent.name)}\n </AvatarFallback>\n </Avatar>\n ))}\n </div>\n {hiddenCount > 0 && (\n <span className=\"text-xs text-muted-foreground\">+{hiddenCount}</span>\n )}\n </>\n ) : (\n <span className=\"text-muted-foreground\">{label}</span>\n )}\n </div>\n <ChevronDown className=\"h-3 w-3 opacity-50\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"w-[260px]\">\n <DropdownMenuLabel className=\"flex items-center justify-between\">\n <span>Participants</span>\n {selectedAgents.length < agentsWithColors.length && (\n <Button variant=\"ghost\" size=\"sm\" className=\"h-6 text-xs\" onClick={selectAll}>\n Select All\n </Button>\n )}\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n {agentsWithColors.map(agent => {\n const isSelected = participantIds.includes(agent.id);\n const isLastSelected = isSelected && participantIds.length === 1;\n \n return (\n <DropdownMenuItem\n key={agent.id}\n onClick={() => toggleParticipant(agent.id)}\n className=\"flex items-center gap-3 p-2 cursor-pointer\"\n disabled={isLastSelected}\n >\n <Avatar className=\"h-6 w-6\">\n <AvatarImage src={agent.avatarUrl} alt={agent.name} />\n <AvatarFallback\n style={{ backgroundColor: agent.color || getAgentColor(agent.id), color: 'white' }}\n className=\"text-[10px]\"\n >\n {getAgentInitials(agent.name)}\n </AvatarFallback>\n </Avatar>\n <div className=\"flex-1 min-w-0\">\n <div className=\"font-medium text-sm truncate\">{agent.name}</div>\n {agent.description && (\n <div className=\"text-xs text-muted-foreground truncate\">{agent.description}</div>\n )}\n </div>\n {isSelected && (\n <Check className=\"h-4 w-4 text-primary shrink-0\" />\n )}\n </DropdownMenuItem>\n );\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n});\n\nParticipantsSelector.displayName = 'ParticipantsSelector';\n\ninterface TargetAgentSelectorProps {\n /** Available agents (should be filtered to participants only) */\n agents: AgentOption[];\n /** Currently targeted agent ID */\n targetAgentId: string | null;\n /** Callback when target changes */\n onTargetChange: (agentId: string | null) => void;\n /** Label for the selector */\n label?: string;\n /** Placeholder when no target is selected */\n placeholder?: string;\n /** Disabled state */\n disabled?: boolean;\n}\n\n/**\n * Single-select dropdown for choosing which agent to address with @mention.\n */\nexport const TargetAgentSelector: React.FC<TargetAgentSelectorProps> = memo(({\n agents,\n targetAgentId,\n onTargetChange,\n label = 'Target',\n placeholder = 'Select agent',\n disabled = false,\n}) => {\n // Assign colors to agents\n const agentsWithColors = useMemo(() => assignAgentColors(agents), [agents]);\n \n // Get selected agent\n const selectedAgent = useMemo(() => \n agentsWithColors.find(a => a.id === targetAgentId),\n [agentsWithColors, targetAgentId]\n );\n \n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n className=\"h-9 px-3 gap-1.5 font-medium text-base hover:bg-accent/50\"\n disabled={disabled}\n >\n <AtSign className=\"h-4 w-4 text-muted-foreground\" />\n {selectedAgent ? (\n <div className=\"flex items-center gap-2\">\n <Avatar className=\"h-5 w-5\">\n <AvatarImage src={selectedAgent.avatarUrl} alt={selectedAgent.name} />\n <AvatarFallback\n style={{ backgroundColor: selectedAgent.color || getAgentColor(selectedAgent.id), color: 'white' }}\n className=\"text-[10px]\"\n >\n {getAgentInitials(selectedAgent.name)}\n </AvatarFallback>\n </Avatar>\n <span className=\"max-w-[150px] truncate\">{selectedAgent.name}</span>\n </div>\n ) : (\n <span className=\"text-muted-foreground\">{placeholder}</span>\n )}\n <ChevronDown className=\"h-4 w-4 opacity-50\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"w-[280px]\">\n <DropdownMenuLabel>{label}</DropdownMenuLabel>\n <DropdownMenuSeparator />\n {agentsWithColors.map(agent => {\n const isSelected = agent.id === targetAgentId;\n \n return (\n <DropdownMenuItem\n key={agent.id}\n onClick={() => onTargetChange(agent.id)}\n className=\"flex items-start gap-3 p-3 cursor-pointer\"\n >\n <Avatar className=\"h-6 w-6 mt-0.5 shrink-0\">\n <AvatarImage src={agent.avatarUrl} alt={agent.name} />\n <AvatarFallback\n style={{ backgroundColor: agent.color || getAgentColor(agent.id), color: 'white' }}\n className=\"text-[10px]\"\n >\n {getAgentInitials(agent.name)}\n </AvatarFallback>\n </Avatar>\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium text-sm\">{agent.name}</span>\n {isSelected && (\n <Check className=\"h-4 w-4 text-primary shrink-0\" />\n )}\n </div>\n {agent.description && (\n <p className=\"text-xs text-muted-foreground mt-0.5 line-clamp-2\">\n {agent.description}\n </p>\n )}\n </div>\n </DropdownMenuItem>\n );\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n});\n\nTargetAgentSelector.displayName = 'TargetAgentSelector';\n\ninterface AgentBadgeProps {\n agent: AgentOption;\n onRemove?: () => void;\n showRemove?: boolean;\n size?: 'sm' | 'md';\n}\n\n/**\n * Badge displaying an agent with optional remove button.\n */\nexport const AgentBadge: React.FC<AgentBadgeProps> = memo(({\n agent,\n onRemove,\n showRemove = false,\n size = 'md',\n}) => {\n const color = agent.color || getAgentColor(agent.id);\n const avatarSize = size === 'sm' ? 'h-4 w-4' : 'h-5 w-5';\n const textSize = size === 'sm' ? 'text-xs' : 'text-sm';\n \n return (\n <Badge\n variant=\"secondary\"\n className=\"flex items-center gap-1.5 pr-1\"\n style={{ borderColor: color, borderWidth: 1 }}\n >\n <Avatar className={avatarSize}>\n <AvatarImage src={agent.avatarUrl} alt={agent.name} />\n <AvatarFallback\n style={{ backgroundColor: color, color: 'white' }}\n className=\"text-[8px]\"\n >\n {getAgentInitials(agent.name)}\n </AvatarFallback>\n </Avatar>\n <span className={textSize}>{agent.name}</span>\n {showRemove && onRemove && (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-4 w-4 ml-0.5 hover:bg-destructive/20\"\n onClick={(e) => {\n e.stopPropagation();\n onRemove();\n }}\n >\n <X className=\"h-3 w-3\" />\n </Button>\n )}\n </Badge>\n );\n});\n\nAgentBadge.displayName = 'AgentBadge';\n","import React, { useState, useRef, useCallback, useEffect, memo } from 'react';\nimport { useChatUserContext } from './UserContext';\nimport {\n AgentOption,\n MediaAttachment,\n FileUploadProgress,\n ChatConfig,\n VoiceComposerState,\n VoiceProvider,\n VoiceSegment,\n VoiceTranscript,\n} from '../../types/chatTypes';\nimport { createObjectUrlFromDataUrl } from '../../lib/utils';\nimport { appendVoiceSegments, mergeVoiceTranscripts, resolveVoiceProviderFactory } from '../../lib/voiceCompose';\nimport { Button } from '../ui/button';\nimport { Textarea } from '../ui/textarea';\nimport { Card, CardContent } from '../ui/card';\nimport { Badge } from '../ui/badge';\nimport { Progress } from '../ui/progress';\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../ui/tooltip';\nimport { VoiceComposer } from './VoiceComposer';\nimport {\n Send,\n Paperclip,\n Mic,\n Image,\n Video,\n FileText,\n X,\n Square,\n Play,\n Pause,\n Loader2,\n} from 'lucide-react';\n\ninterface ChatInputProps {\n value: string;\n onChange: (value: string) => void;\n onSubmit: (content: string, attachments: MediaAttachment[]) => void;\n attachments: MediaAttachment[];\n onAttachmentsChange: (attachments: MediaAttachment[]) => void;\n placeholder?: string;\n disabled?: boolean;\n isGenerating?: boolean;\n onStopGeneration?: () => void;\n enableFileUpload?: boolean;\n enableAudioRecording?: boolean;\n maxAttachments?: number;\n maxFileSize?: number;\n acceptedFileTypes?: string[];\n className?: string;\n config?: ChatConfig;\n mentionAgents?: AgentOption[];\n onTargetAgentChange?: (agentId: string | null) => void;\n}\n\ninterface MentionMatch {\n start: number;\n end: number;\n query: string;\n}\n\nfunction getActiveMentionMatch(value: string, caret: number): MentionMatch | null {\n const prefix = value.slice(0, caret);\n const match = /(^|\\s)@([\\w.-]*)$/.exec(prefix);\n if (!match) return null;\n\n const query = match[2] ?? '';\n return {\n start: prefix.length - query.length - 1,\n end: caret,\n query,\n };\n}\n\nfunction resolveTargetFromMentions(\n value: string,\n agents: AgentOption[],\n): AgentOption | null {\n const matches = value.matchAll(/(^|\\s)@([\\w.-]+)/g);\n\n for (const match of matches) {\n const mention = match[2]?.toLowerCase();\n if (!mention) continue;\n\n const agent = agents.find((candidate) =>\n candidate.id.toLowerCase() === mention ||\n candidate.name.toLowerCase() === mention\n );\n if (agent) return agent;\n }\n\n return null;\n}\n\n// File upload progress component - memoized\nconst FileUploadItem: React.FC<{\n file: { name: string; type?: string; size?: number };\n progress: number;\n onCancel: () => void;\n}> = memo(function FileUploadItem({ file, progress, onCancel }) {\n const guessTypeFromName = (name?: string): string => {\n const ext = (name || '').split('.').pop()?.toLowerCase();\n switch (ext) {\n case 'jpg':\n case 'jpeg':\n case 'png':\n case 'gif':\n case 'webp':\n case 'bmp':\n case 'svg':\n return 'image/*';\n case 'mp4':\n case 'mov':\n case 'm4v':\n case 'webm':\n return 'video/*';\n case 'mp3':\n case 'wav':\n case 'm4a':\n case 'ogg':\n return 'audio/*';\n default:\n return '';\n }\n };\n\n const getFileIcon = (type?: string, name?: string) => {\n const t = typeof type === 'string' && type.length > 0 ? type : guessTypeFromName(name);\n if (t.startsWith('image/')) return <Image className=\"h-4 w-4\" />;\n if (t.startsWith('video/')) return <Video className=\"h-4 w-4\" />;\n if (t.startsWith('audio/')) return <Mic className=\"h-4 w-4\" />;\n return <FileText className=\"h-4 w-4\" />;\n };\n\n const formatFileSize = (bytes: number) => {\n if (bytes === 0) return '0 Bytes';\n const k = 1024;\n const sizes = ['Bytes', 'KB', 'MB', 'GB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\n };\n\n return (\n <Card className=\"relative\">\n <CardContent className=\"p-3\">\n <div className=\"flex items-center gap-3\">\n {getFileIcon(file.type, file.name)}\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium truncate\">{file.name}</p>\n <p className=\"text-xs text-muted-foreground\">\n {formatFileSize(file.size ?? 0)}\n </p>\n <Progress value={progress} className=\"h-1 mt-1\" />\n </div>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-6 w-6\"\n onClick={onCancel}\n >\n <X className=\"h-3 w-3\" />\n </Button>\n </div>\n </CardContent>\n </Card>\n );\n});\n\n// Attachment preview component - memoized\nconst AttachmentPreview: React.FC<{\n attachment: MediaAttachment;\n onRemove: () => void;\n}> = memo(function AttachmentPreview({ attachment, onRemove }) {\n const [isPlaying, setIsPlaying] = useState(false);\n const [audioPlaybackSrc, setAudioPlaybackSrc] = useState(attachment.dataUrl);\n const audioRef = useRef<HTMLAudioElement>(null);\n\n useEffect(() => {\n if (attachment.kind !== 'audio' || !attachment.dataUrl.startsWith('data:')) {\n setAudioPlaybackSrc(attachment.dataUrl);\n return;\n }\n\n const objectUrl = createObjectUrlFromDataUrl(attachment.dataUrl);\n if (!objectUrl) {\n setAudioPlaybackSrc(attachment.dataUrl);\n return;\n }\n\n setAudioPlaybackSrc(objectUrl);\n\n return () => {\n URL.revokeObjectURL(objectUrl);\n };\n }, [attachment.kind, attachment.dataUrl]);\n\n const handlePlayPause = () => {\n if (audioRef.current) {\n if (isPlaying) {\n audioRef.current.pause();\n } else {\n audioRef.current.play();\n }\n setIsPlaying(!isPlaying);\n }\n };\n\n const formatDuration = (ms?: number) => {\n if (!ms) return '';\n const seconds = Math.floor(ms / 1000);\n const minutes = Math.floor(seconds / 60);\n return `${minutes}:${(seconds % 60).toString().padStart(2, '0')}`;\n };\n\n return (\n <Card className=\"relative group\">\n <CardContent className=\"p-2\">\n {attachment.kind === 'image' && (\n <div className=\"relative\">\n <img\n src={attachment.dataUrl}\n alt={attachment.fileName || 'Attachment'}\n className=\"w-full h-20 object-cover rounded\"\n />\n <div className=\"absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity rounded flex items-center justify-center\">\n <Button\n variant=\"destructive\"\n size=\"icon\"\n className=\"h-6 w-6\"\n onClick={onRemove}\n >\n <X className=\"h-3 w-3\" />\n </Button>\n </div>\n </div>\n )}\n\n {attachment.kind === 'video' && (\n <div className=\"relative\">\n <video\n src={attachment.dataUrl}\n poster={attachment.poster}\n className=\"w-full h-20 object-cover rounded\"\n muted\n />\n <div className=\"absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity rounded flex items-center justify-center\">\n <Button\n variant=\"destructive\"\n size=\"icon\"\n className=\"h-6 w-6\"\n onClick={onRemove}\n >\n <X className=\"h-3 w-3\" />\n </Button>\n </div>\n <Badge className=\"absolute bottom-1 right-1 text-xs\">\n {formatDuration(attachment.durationMs)}\n </Badge>\n </div>\n )}\n\n {attachment.kind === 'audio' && (\n <div className=\"flex items-center gap-2 p-2\">\n <Button\n variant=\"outline\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={handlePlayPause}\n >\n {isPlaying ? <Pause className=\"h-3 w-3\" /> : <Play className=\"h-3 w-3\" />}\n </Button>\n <div className=\"flex-1\">\n <p className=\"text-xs font-medium\">\n {attachment.fileName || 'Audio'}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {formatDuration(attachment.durationMs)}\n </p>\n </div>\n <audio\n ref={audioRef}\n onPlay={() => setIsPlaying(true)}\n onPause={() => setIsPlaying(false)}\n onEnded={() => setIsPlaying(false)}\n preload=\"metadata\"\n >\n <source src={audioPlaybackSrc} type={attachment.mimeType} />\n </audio>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity\"\n onClick={onRemove}\n >\n <X className=\"h-3 w-3\" />\n </Button>\n </div>\n )}\n\n {attachment.fileName && attachment.kind !== 'audio' && (\n <div className=\"absolute bottom-0 left-0 right-0 bg-black/70 text-white text-xs p-1 rounded-b\">\n <p className=\"truncate\">{attachment.fileName}</p>\n </div>\n )}\n </CardContent>\n </Card>\n );\n});\n\n// Audio recording component - memoized\nconst AudioRecorder: React.FC<{\n isRecording: boolean;\n onStartRecording: () => void;\n onStopRecording: () => void;\n onCancel: () => void;\n recordingDuration: number;\n config?: ChatConfig;\n}> = memo(function AudioRecorder({ isRecording, onStartRecording, onStopRecording, onCancel, recordingDuration, config }) {\n const formatTime = (seconds: number) => {\n const mins = Math.floor(seconds / 60);\n const secs = seconds % 60;\n return `${mins}:${secs.toString().padStart(2, '0')}`;\n };\n\n if (!isRecording) {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={onStartRecording}\n className=\"h-10 w-10\"\n >\n <Mic className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>{config?.labels?.recordAudioTooltip}</TooltipContent>\n </Tooltip>\n );\n }\n\n return (\n <Card className=\"border-red-200 bg-red-50 dark:border-red-800 dark:bg-red-950\">\n <CardContent className=\"p-3\">\n <div className=\"flex items-center gap-3\">\n <div className=\"flex items-center gap-2\">\n <div className=\"h-3 w-3 bg-red-500 rounded-full animate-pulse\" />\n <span className=\"text-sm font-medium text-red-700 dark:text-red-300\">\n {config?.labels?.voiceListening || 'Recording'}\n </span>\n </div>\n <Badge variant=\"outline\" className=\"text-xs\">\n {formatTime(recordingDuration)}\n </Badge>\n <div className=\"flex gap-1 ml-auto\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={onCancel}\n >\n <X className=\"h-3 w-3 mr-1\" />\n {config?.labels?.cancel || 'Cancel'}\n </Button>\n <Button\n variant=\"default\"\n size=\"sm\"\n onClick={onStopRecording}\n >\n <Square className=\"h-3 w-3 mr-1\" />\n {config?.labels?.voiceStop || 'Stop'}\n </Button>\n </div>\n </div>\n </CardContent>\n </Card>\n );\n});\n\nconst resolveVoiceErrorMessage = (error: unknown, config?: ChatConfig): string => {\n if (error instanceof DOMException && error.name === 'NotAllowedError') {\n return config?.labels?.voicePermissionDenied || 'Microphone access was denied.';\n }\n\n if (error instanceof Error && error.message.trim().length > 0) {\n return error.message;\n }\n\n return config?.labels?.voiceCaptureError || 'Unable to capture audio.';\n};\n\nconst clearVoiceTranscript = (): VoiceTranscript => ({});\nconst resolveVoiceSegmentDuration = (segment: VoiceSegment): number => segment.attachment.durationMs ?? 0;\n\nexport const ChatInput: React.FC<ChatInputProps> = memo(function ChatInput({\n value,\n onChange,\n onSubmit,\n attachments,\n onAttachmentsChange,\n placeholder = 'Type your message...',\n disabled = false,\n isGenerating = false,\n onStopGeneration,\n enableFileUpload = true,\n enableAudioRecording = true,\n maxAttachments = 4,\n maxFileSize = 10 * 1024 * 1024, // 10MB\n acceptedFileTypes = ['image/*', 'video/*', 'audio/*'],\n className = '',\n config,\n mentionAgents = [],\n onTargetAgentChange,\n}: ChatInputProps) {\n const voiceComposeEnabled = config?.voiceCompose?.enabled === true;\n const voiceDefaultMode = config?.voiceCompose?.defaultMode ?? 'text';\n const voiceReviewMode = config?.voiceCompose?.reviewMode ?? 'manual';\n const voiceAutoSendDelayMs = config?.voiceCompose?.autoSendDelayMs ?? 5000;\n const voicePersistComposer = config?.voiceCompose?.persistComposer ?? true;\n const voiceShowTranscriptPreview = config?.voiceCompose?.showTranscriptPreview ?? true;\n const voiceTranscriptMode = config?.voiceCompose?.transcriptMode ?? 'final-only';\n const voiceMaxRecordingMs = config?.voiceCompose?.maxRecordingMs;\n\n const [isRecording, setIsRecording] = useState(false);\n const { setContext } = useChatUserContext();\n const [recordingDuration, setRecordingDuration] = useState(0);\n const [uploadProgress, setUploadProgress] = useState<Map<string, FileUploadProgress>>(new Map());\n const [isVoiceComposerOpen, setIsVoiceComposerOpen] = useState(\n () => voiceComposeEnabled && voiceDefaultMode === 'voice',\n );\n const [voiceState, setVoiceState] = useState<VoiceComposerState>('idle');\n const [voiceDraft, setVoiceDraft] = useState<VoiceSegment | null>(null);\n const [voiceTranscript, setVoiceTranscript] = useState<VoiceTranscript>(clearVoiceTranscript);\n const [voiceDurationMs, setVoiceDurationMs] = useState(0);\n const [voiceAudioLevel, setVoiceAudioLevel] = useState(0);\n const [voiceCountdownMs, setVoiceCountdownMs] = useState(0);\n const [isVoiceAutoSendActive, setIsVoiceAutoSendActive] = useState(false);\n const [voiceError, setVoiceError] = useState<string | null>(null);\n const [activeMention, setActiveMention] = useState<MentionMatch | null>(null);\n const [activeMentionIndex, setActiveMentionIndex] = useState(0);\n\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const fileInputRef = useRef<HTMLInputElement>(null);\n const mediaRecorderRef = useRef<MediaRecorder | null>(null);\n const recordingStartTime = useRef<number>(0);\n const recordingInterval = useRef<ReturnType<typeof setInterval> | null>(null);\n const mediaStreamRef = useRef<MediaStream | null>(null);\n const voiceProviderRef = useRef<VoiceProvider | null>(null);\n const voiceDraftRef = useRef<VoiceSegment | null>(null);\n const voiceAppendBaseRef = useRef<VoiceSegment | null>(null);\n const voiceAppendBaseDurationRef = useRef(0);\n\n const filteredMentionAgents = React.useMemo(() => {\n if (!activeMention || mentionAgents.length === 0) return [];\n\n const query = activeMention.query.trim().toLowerCase();\n const rank = (agent: AgentOption) => {\n const id = agent.id.toLowerCase();\n const name = agent.name.toLowerCase();\n if (!query) return 0;\n if (name.startsWith(query) || id.startsWith(query)) return 0;\n if (name.includes(query) || id.includes(query)) return 1;\n return 2;\n };\n\n return mentionAgents\n .filter((agent) => rank(agent) < 2)\n .sort((left, right) => {\n const rankDiff = rank(left) - rank(right);\n if (rankDiff !== 0) return rankDiff;\n return left.name.localeCompare(right.name);\n })\n .slice(0, 6);\n }, [activeMention, mentionAgents]);\n\n const isMentionMenuOpen = filteredMentionAgents.length > 0;\n\n const syncMentionState = useCallback((nextValue: string, nextCaret?: number) => {\n const caret = typeof nextCaret === 'number'\n ? nextCaret\n : textareaRef.current?.selectionStart ?? nextValue.length;\n const nextMatch = getActiveMentionMatch(nextValue, caret);\n setActiveMention((prev) => {\n if (\n prev?.start === nextMatch?.start &&\n prev?.end === nextMatch?.end &&\n prev?.query === nextMatch?.query\n ) {\n return prev;\n }\n return nextMatch;\n });\n setActiveMentionIndex(0);\n }, []);\n\n // Cleanup recording on unmount\n useEffect(() => {\n return () => {\n if (mediaStreamRef.current) {\n mediaStreamRef.current.getTracks().forEach(track => track.stop());\n }\n if (recordingInterval.current) {\n clearInterval(recordingInterval.current);\n }\n if (voiceProviderRef.current) {\n void voiceProviderRef.current.destroy();\n voiceProviderRef.current = null;\n }\n };\n }, []);\n\n useEffect(() => {\n voiceDraftRef.current = voiceDraft;\n }, [voiceDraft]);\n\n useEffect(() => {\n if (!isMentionMenuOpen) {\n setActiveMentionIndex(0);\n return;\n }\n setActiveMentionIndex((prev) =>\n prev >= filteredMentionAgents.length ? 0 : prev,\n );\n }, [filteredMentionAgents.length, isMentionMenuOpen]);\n\n const selectMentionAgent = useCallback((agent: AgentOption) => {\n if (!activeMention) return;\n\n const replacement = `@${agent.name} `;\n const nextValue =\n value.slice(0, activeMention.start) +\n replacement +\n value.slice(activeMention.end);\n const nextCaret = activeMention.start + replacement.length;\n\n onChange(nextValue);\n onTargetAgentChange?.(agent.id);\n setActiveMention(null);\n setActiveMentionIndex(0);\n\n requestAnimationFrame(() => {\n textareaRef.current?.focus();\n textareaRef.current?.setSelectionRange(nextCaret, nextCaret);\n });\n }, [activeMention, onChange, onTargetAgentChange, value]);\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n if ((!value.trim() && attachments.length === 0) || disabled || isGenerating) return;\n\n const mentionedAgent = resolveTargetFromMentions(value, mentionAgents);\n if (mentionedAgent) {\n onTargetAgentChange?.(mentionedAgent.id);\n }\n\n onSubmit(value.trim(), attachments);\n onChange('');\n onAttachmentsChange([]);\n setActiveMention(null);\n setActiveMentionIndex(0);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (isMentionMenuOpen) {\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n setActiveMentionIndex((prev) =>\n prev >= filteredMentionAgents.length - 1 ? 0 : prev + 1,\n );\n return;\n }\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n setActiveMentionIndex((prev) =>\n prev <= 0 ? filteredMentionAgents.length - 1 : prev - 1,\n );\n return;\n }\n if ((e.key === 'Enter' || e.key === 'Tab') && filteredMentionAgents[activeMentionIndex]) {\n e.preventDefault();\n selectMentionAgent(filteredMentionAgents[activeMentionIndex]);\n return;\n }\n if (e.key === 'Escape') {\n e.preventDefault();\n setActiveMention(null);\n setActiveMentionIndex(0);\n return;\n }\n }\n\n if (e.key === 'Enter' && !e.shiftKey && !e.ctrlKey && window.innerWidth > 768) {\n e.preventDefault();\n handleSubmit(e as any);\n }\n };\n\n const processFile = async (file: File): Promise<MediaAttachment | null> => {\n if (file.size > maxFileSize) {\n alert(`File too large. Max allowed: ${Math.round(maxFileSize / 1024 / 1024)}MB`);\n return null;\n }\n\n const fileId = `${Date.now()}_${Math.random().toString(36).slice(2)}`;\n\n // Start upload progress\n setUploadProgress(prev => new Map(prev.set(fileId, {\n fileName: file.name,\n progress: 0,\n status: 'uploading',\n })));\n\n try {\n // Simulate upload progress\n for (let progress = 0; progress <= 100; progress += 20) {\n await new Promise(resolve => setTimeout(resolve, 100));\n setUploadProgress(prev => new Map(prev.set(fileId, {\n fileName: file.name,\n progress,\n status: 'uploading',\n })));\n }\n\n const dataUrl = await new Promise<string>((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result as string);\n reader.onerror = reject;\n reader.readAsDataURL(file);\n });\n\n setUploadProgress(prev => {\n const newMap = new Map(prev);\n newMap.delete(fileId);\n return newMap;\n });\n\n const attachment: MediaAttachment = {\n kind: file.type.startsWith('image/') ? 'image' :\n file.type.startsWith('video/') ? 'video' :\n file.type.startsWith('audio/') ? 'audio' : 'image',\n dataUrl,\n mimeType: file.type,\n fileName: file.name,\n size: file.size,\n };\n\n // For video files, try to get duration\n if (attachment.kind === 'video') {\n try {\n const video = document.createElement('video');\n video.src = dataUrl;\n await new Promise((resolve) => {\n video.onloadedmetadata = resolve;\n });\n attachment.durationMs = video.duration * 1000;\n } catch (error) {\n console.warn('Could not get video duration:', error);\n }\n }\n\n // If it's an image, mark as latest reference image in shared context\n if (attachment.kind === 'image') {\n setContext({ lastReferenceImage: { dataUrl: attachment.dataUrl, mimeType: attachment.mimeType, addedAt: Date.now() } });\n }\n return attachment;\n } catch (error) {\n console.error('Error processing file:', error);\n setUploadProgress(prev => {\n const newMap = new Map(prev);\n newMap.delete(fileId);\n return newMap;\n });\n alert('Failed to process file');\n return null;\n }\n };\n\n const handleFileSelect = async (e: React.ChangeEvent<HTMLInputElement>) => {\n const files = e.target.files;\n if (!files) return;\n\n const remainingSlots = maxAttachments - attachments.length;\n const filesToProcess = Array.from(files).slice(0, remainingSlots);\n\n for (const file of filesToProcess) {\n const attachment = await processFile(file);\n if (attachment) {\n onAttachmentsChange([...attachments, attachment]);\n }\n }\n\n // Reset input\n e.target.value = '';\n };\n\n const handleDrop = useCallback(async (e: React.DragEvent) => {\n e.preventDefault();\n if (!enableFileUpload) return;\n\n const files = Array.from(e.dataTransfer.files);\n const remainingSlots = maxAttachments - attachments.length;\n const filesToProcess = files.slice(0, remainingSlots);\n\n for (const file of filesToProcess) {\n const attachment = await processFile(file);\n if (attachment) {\n onAttachmentsChange([...attachments, attachment]);\n }\n }\n }, [attachments, enableFileUpload, maxAttachments, onAttachmentsChange]);\n\n const handleDragOver = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n }, []);\n\n const startRecording = async () => {\n try {\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n mediaStreamRef.current = stream;\n\n const mediaRecorder = new MediaRecorder(stream);\n mediaRecorderRef.current = mediaRecorder;\n\n const chunks: BlobPart[] = [];\n mediaRecorder.ondataavailable = (e) => {\n chunks.push(e.data);\n };\n\n mediaRecorder.onstop = async () => {\n const blob = new Blob(chunks, { type: 'audio/webm' });\n const dataUrl = await new Promise<string>((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result as string);\n reader.onerror = reject;\n reader.readAsDataURL(blob);\n });\n\n const attachment: MediaAttachment = {\n kind: 'audio',\n dataUrl,\n mimeType: blob.type,\n durationMs: recordingDuration * 1000,\n fileName: `audio_${new Date().toISOString().slice(0, 19)}.webm`,\n size: blob.size,\n };\n\n onAttachmentsChange([...attachments, attachment]);\n\n // Cleanup\n if (mediaStreamRef.current) {\n mediaStreamRef.current.getTracks().forEach(track => track.stop());\n mediaStreamRef.current = null;\n }\n };\n\n recordingStartTime.current = Date.now();\n setRecordingDuration(0);\n setIsRecording(true);\n mediaRecorder.start();\n\n recordingInterval.current = setInterval(() => {\n const duration = Math.floor((Date.now() - recordingStartTime.current) / 1000);\n setRecordingDuration(duration);\n }, 1000);\n\n } catch (error) {\n console.error('Error starting recording:', error);\n alert(config?.labels?.voicePermissionDenied || 'Microphone access was denied.');\n }\n };\n\n const stopRecording = () => {\n if (mediaRecorderRef.current && isRecording) {\n mediaRecorderRef.current.stop();\n setIsRecording(false);\n if (recordingInterval.current) {\n clearInterval(recordingInterval.current);\n }\n }\n };\n\n const cancelRecording = () => {\n if (mediaRecorderRef.current && isRecording) {\n mediaRecorderRef.current.stop();\n setIsRecording(false);\n if (recordingInterval.current) {\n clearInterval(recordingInterval.current);\n }\n // Don't process the recording\n if (mediaStreamRef.current) {\n mediaStreamRef.current.getTracks().forEach(track => track.stop());\n mediaStreamRef.current = null;\n }\n }\n };\n\n const resetVoiceComposerState = useCallback((nextState: VoiceComposerState = 'idle') => {\n setVoiceState(nextState);\n setVoiceDraft(null);\n voiceDraftRef.current = null;\n voiceAppendBaseRef.current = null;\n voiceAppendBaseDurationRef.current = 0;\n setVoiceTranscript(clearVoiceTranscript());\n setVoiceDurationMs(0);\n setVoiceAudioLevel(0);\n setVoiceCountdownMs(0);\n setIsVoiceAutoSendActive(false);\n setVoiceError(null);\n }, []);\n\n const armVoiceDraftForAppend = useCallback((segment: VoiceSegment | null) => {\n voiceAppendBaseRef.current = segment;\n voiceAppendBaseDurationRef.current = segment ? resolveVoiceSegmentDuration(segment) : 0;\n }, []);\n\n const handleVoiceProviderStateChange = useCallback((nextState: VoiceComposerState) => {\n if (\n voiceReviewMode === 'armed' &&\n (nextState === 'waiting_for_speech' || nextState === 'listening')\n ) {\n const currentDraft = voiceDraftRef.current;\n if (currentDraft) {\n armVoiceDraftForAppend(currentDraft);\n }\n }\n\n if (\n voiceReviewMode === 'armed' &&\n nextState === 'listening' &&\n voiceDraftRef.current\n ) {\n setVoiceCountdownMs(voiceAutoSendDelayMs);\n setIsVoiceAutoSendActive(false);\n }\n\n setVoiceState(nextState);\n }, [armVoiceDraftForAppend, voiceAutoSendDelayMs, voiceReviewMode]);\n\n const ensureVoiceProvider = useCallback(async () => {\n if (voiceProviderRef.current) {\n return voiceProviderRef.current;\n }\n\n const createProvider = resolveVoiceProviderFactory(config?.voiceCompose?.createProvider);\n const provider = await createProvider({\n onStateChange: handleVoiceProviderStateChange,\n onAudioLevelChange: setVoiceAudioLevel,\n onDurationChange: (durationMs) => {\n setVoiceDurationMs(voiceAppendBaseDurationRef.current + durationMs);\n },\n onTranscriptChange: (transcript) => {\n const baseTranscript = voiceAppendBaseRef.current?.transcript;\n setVoiceTranscript(\n baseTranscript\n ? mergeVoiceTranscripts(baseTranscript, transcript)\n : transcript,\n );\n },\n onSegmentReady: (segment) => {\n void (async () => {\n const previousSegment = voiceAppendBaseRef.current;\n\n try {\n const nextSegment = previousSegment\n ? await appendVoiceSegments(previousSegment, segment)\n : segment;\n\n voiceDraftRef.current = nextSegment;\n setVoiceDraft(nextSegment);\n setVoiceTranscript(nextSegment.transcript ?? clearVoiceTranscript());\n setVoiceDurationMs(resolveVoiceSegmentDuration(nextSegment));\n setVoiceAudioLevel(0);\n setVoiceCountdownMs(voiceAutoSendDelayMs);\n setIsVoiceAutoSendActive(voiceAutoSendDelayMs > 0);\n setVoiceError(null);\n if (voiceReviewMode === 'armed') {\n armVoiceDraftForAppend(nextSegment);\n } else {\n armVoiceDraftForAppend(null);\n }\n setVoiceState((currentState) =>\n voiceReviewMode === 'armed' && (\n currentState === 'waiting_for_speech' ||\n currentState === 'listening'\n )\n ? currentState\n : 'review');\n } catch (error) {\n const resolvedError = resolveVoiceErrorMessage(error, config);\n\n armVoiceDraftForAppend(null);\n setVoiceAudioLevel(0);\n setVoiceCountdownMs(0);\n setIsVoiceAutoSendActive(false);\n\n if (previousSegment) {\n voiceDraftRef.current = previousSegment;\n setVoiceDraft(previousSegment);\n setVoiceTranscript(previousSegment.transcript ?? clearVoiceTranscript());\n setVoiceDurationMs(resolveVoiceSegmentDuration(previousSegment));\n setVoiceError(resolvedError);\n setVoiceState('review');\n return;\n }\n\n voiceDraftRef.current = null;\n setVoiceDraft(null);\n setVoiceTranscript(clearVoiceTranscript());\n setVoiceDurationMs(0);\n setVoiceError(resolvedError);\n setVoiceState('error');\n }\n })();\n },\n onError: (error) => {\n const previousSegment = voiceAppendBaseRef.current;\n armVoiceDraftForAppend(null);\n setVoiceError(resolveVoiceErrorMessage(error, config));\n setVoiceAudioLevel(0);\n setVoiceCountdownMs(0);\n setIsVoiceAutoSendActive(false);\n\n if (previousSegment) {\n voiceDraftRef.current = previousSegment;\n setVoiceDraft(previousSegment);\n setVoiceTranscript(previousSegment.transcript ?? clearVoiceTranscript());\n setVoiceDurationMs(resolveVoiceSegmentDuration(previousSegment));\n setVoiceState('review');\n return;\n }\n\n voiceDraftRef.current = null;\n setVoiceDraft(null);\n setVoiceTranscript(clearVoiceTranscript());\n setVoiceDurationMs(0);\n setVoiceState('error');\n },\n }, {\n maxRecordingMs: voiceMaxRecordingMs,\n });\n\n voiceProviderRef.current = provider;\n return provider;\n }, [armVoiceDraftForAppend, config, handleVoiceProviderStateChange, voiceAutoSendDelayMs, voiceMaxRecordingMs, voiceReviewMode]);\n\n const closeVoiceComposer = useCallback(async () => {\n voiceAppendBaseRef.current = null;\n voiceAppendBaseDurationRef.current = 0;\n setIsVoiceComposerOpen(false);\n setVoiceError(null);\n setVoiceCountdownMs(0);\n setVoiceAudioLevel(0);\n setVoiceTranscript(clearVoiceTranscript());\n setVoiceDraft(null);\n voiceDraftRef.current = null;\n setVoiceDurationMs(0);\n setVoiceState('idle');\n\n if (voiceProviderRef.current) {\n await voiceProviderRef.current.cancel();\n }\n }, []);\n\n const startVoiceCapture = useCallback(async (appendToDraft = false) => {\n if (disabled || isGenerating) {\n return;\n }\n\n const previousDraft = appendToDraft ? voiceDraftRef.current : null;\n const previousDurationMs = previousDraft ? resolveVoiceSegmentDuration(previousDraft) : 0;\n\n setIsVoiceComposerOpen(true);\n setVoiceError(null);\n setVoiceCountdownMs(0);\n setVoiceAudioLevel(0);\n setIsVoiceAutoSendActive(false);\n voiceAppendBaseRef.current = previousDraft;\n voiceAppendBaseDurationRef.current = previousDurationMs;\n\n if (!previousDraft) {\n setVoiceDraft(null);\n voiceDraftRef.current = null;\n setVoiceTranscript(clearVoiceTranscript());\n setVoiceDurationMs(0);\n } else {\n setVoiceTranscript(previousDraft.transcript ?? clearVoiceTranscript());\n setVoiceDurationMs(previousDurationMs);\n }\n\n try {\n const provider = await ensureVoiceProvider();\n await provider.start();\n } catch (error) {\n const resolvedError = resolveVoiceErrorMessage(error, config);\n voiceAppendBaseRef.current = null;\n voiceAppendBaseDurationRef.current = 0;\n setVoiceAudioLevel(0);\n setVoiceCountdownMs(0);\n setIsVoiceAutoSendActive(false);\n\n if (previousDraft) {\n voiceDraftRef.current = previousDraft;\n setVoiceDraft(previousDraft);\n setVoiceTranscript(previousDraft.transcript ?? clearVoiceTranscript());\n setVoiceDurationMs(previousDurationMs);\n setVoiceError(resolvedError);\n setVoiceState('review');\n return;\n }\n\n voiceDraftRef.current = null;\n setVoiceDraft(null);\n setVoiceTranscript(clearVoiceTranscript());\n setVoiceDurationMs(0);\n setVoiceError(resolvedError);\n setVoiceState('error');\n }\n }, [disabled, isGenerating, ensureVoiceProvider, config]);\n\n const stopVoiceCapture = useCallback(async () => {\n if (!voiceProviderRef.current) return;\n\n try {\n await voiceProviderRef.current.stop();\n } catch (error) {\n setVoiceError(resolveVoiceErrorMessage(error, config));\n setVoiceState('error');\n }\n }, [config]);\n\n const cancelVoiceCapture = useCallback(async () => {\n voiceAppendBaseRef.current = null;\n voiceAppendBaseDurationRef.current = 0;\n if (voiceProviderRef.current) {\n await voiceProviderRef.current.cancel();\n }\n\n resetVoiceComposerState('idle');\n }, [resetVoiceComposerState]);\n\n const finalizeVoiceComposerAfterSend = useCallback(() => {\n if (voicePersistComposer) {\n resetVoiceComposerState('idle');\n setIsVoiceComposerOpen(true);\n return;\n }\n\n void closeVoiceComposer();\n }, [voicePersistComposer, resetVoiceComposerState, closeVoiceComposer]);\n\n const sendVoiceDraft = useCallback(() => {\n void (async () => {\n if (!voiceDraft || disabled || isGenerating) {\n return;\n }\n\n setVoiceState('sending');\n setVoiceCountdownMs(0);\n setIsVoiceAutoSendActive(false);\n\n if (voiceProviderRef.current) {\n await voiceProviderRef.current.cancel();\n }\n\n onSubmit('', [...attachments, voiceDraft.attachment]);\n onChange('');\n onAttachmentsChange([]);\n finalizeVoiceComposerAfterSend();\n })();\n }, [\n voiceDraft,\n disabled,\n isGenerating,\n onSubmit,\n attachments,\n onChange,\n onAttachmentsChange,\n finalizeVoiceComposerAfterSend,\n ]);\n\n const cancelVoiceAutoSend = useCallback(() => {\n void (async () => {\n if (voiceReviewMode === 'armed' && voiceProviderRef.current) {\n await voiceProviderRef.current.cancel();\n }\n\n armVoiceDraftForAppend(null);\n setVoiceAudioLevel(0);\n setVoiceState('review');\n })();\n\n setVoiceCountdownMs(0);\n setIsVoiceAutoSendActive(false);\n }, [armVoiceDraftForAppend, voiceReviewMode]);\n\n const pauseVoiceReview = useCallback(async () => {\n if (voiceState === 'listening') {\n await stopVoiceCapture();\n return;\n }\n\n if (voiceReviewMode === 'armed' && voiceProviderRef.current) {\n await voiceProviderRef.current.cancel();\n }\n\n armVoiceDraftForAppend(null);\n setVoiceAudioLevel(0);\n setVoiceState('review');\n }, [armVoiceDraftForAppend, stopVoiceCapture, voiceReviewMode, voiceState]);\n\n useEffect(() => {\n if (\n !voiceDraft ||\n voiceAutoSendDelayMs <= 0 ||\n !isVoiceAutoSendActive\n ) {\n return;\n }\n\n const canContinueCounting = voiceState === 'review' || (\n voiceReviewMode === 'armed' &&\n voiceState === 'waiting_for_speech'\n );\n\n if (!canContinueCounting) {\n return;\n }\n\n const timer = setInterval(() => {\n setVoiceCountdownMs((previous) => {\n const remaining = Math.max(0, previous - 100);\n\n if (remaining <= 0) {\n clearInterval(timer);\n queueMicrotask(() => {\n sendVoiceDraft();\n });\n }\n\n return remaining;\n });\n }, 100);\n\n return () => clearInterval(timer);\n }, [voiceState, voiceDraft, voiceReviewMode, voiceAutoSendDelayMs, isVoiceAutoSendActive, sendVoiceDraft]);\n\n const removeAttachment = (index: number) => {\n const newAttachments = attachments.filter((_, i) => i !== index);\n onAttachmentsChange(newAttachments);\n };\n\n const canAddMoreAttachments = attachments.length < maxAttachments;\n const showVoiceComposer = voiceComposeEnabled && isVoiceComposerOpen;\n\n return (\n <TooltipProvider>\n {/* <Card className={`border-t py-0 bg-transparent ${className}`}> */}\n {/* <CardContent className=\"p-4 pb-1 space-y-4 bg-transparent\"> */}\n {/* Upload progress */}\n <div className={`border-t py-0 bg-transparent ${className}`}>\n <div className=\"px-0 md:p-2 pb-1 space-y-4 bg-transparent\">\n {uploadProgress.size > 0 && (\n <div className=\"space-y-2\">\n {Array.from(uploadProgress.entries()).map(([id, progress]) => (\n <FileUploadItem\n key={id}\n file={{ name: progress.fileName } as File}\n progress={progress.progress}\n onCancel={() => {\n setUploadProgress(prev => {\n const newMap = new Map(prev);\n newMap.delete(id);\n return newMap;\n });\n }}\n />\n ))}\n </div>\n )}\n\n {/* Audio recording */}\n {isRecording && (\n <AudioRecorder\n isRecording={isRecording}\n onStartRecording={startRecording}\n onStopRecording={stopRecording}\n onCancel={cancelRecording}\n recordingDuration={recordingDuration}\n config={config}\n />\n )}\n\n {/* Attachments preview */}\n {attachments.length > 0 && (\n <div className=\"grid grid-cols-4 gap-2\">\n {attachments.map((attachment, index) => (\n <AttachmentPreview\n key={index}\n attachment={attachment}\n onRemove={() => removeAttachment(index)}\n />\n ))}\n </div>\n )}\n\n {/* Input area */}\n {showVoiceComposer ? (\n <div className=\"mb-1 flex justify-center\">\n <VoiceComposer\n state={voiceState}\n transcript={voiceTranscript}\n transcriptMode={voiceTranscriptMode}\n showTranscriptPreview={voiceShowTranscriptPreview}\n attachment={voiceDraft?.attachment ?? null}\n durationMs={voiceDurationMs}\n audioLevel={voiceAudioLevel}\n countdownMs={voiceCountdownMs}\n autoSendDelayMs={voiceAutoSendDelayMs}\n isAutoSendActive={isVoiceAutoSendActive}\n reviewMode={voiceReviewMode}\n errorMessage={voiceError}\n disabled={disabled || isGenerating}\n labels={config?.labels}\n onStart={() => {\n void startVoiceCapture();\n }}\n onStop={() => {\n void stopVoiceCapture();\n }}\n onPauseReview={() => {\n void pauseVoiceReview();\n }}\n onCancelAutoSend={() => {\n cancelVoiceAutoSend();\n }}\n onDiscard={() => {\n void cancelVoiceCapture();\n }}\n onRecordAgain={() => {\n void startVoiceCapture(true);\n }}\n onSendNow={sendVoiceDraft}\n onExit={() => {\n void closeVoiceComposer();\n }}\n />\n </div>\n ) : (\n <form onSubmit={handleSubmit} className=\"mb-1 flex justify-center\">\n <div\n className=\"flex items-end gap-2 p-3 border rounded-lg bg-background w-full md:min-w-3xl max-w-3xl\"\n onDrop={handleDrop}\n onDragOver={handleDragOver}\n >\n {/* File upload */}\n {enableFileUpload && canAddMoreAttachments && (\n <>\n <input\n ref={fileInputRef}\n type=\"file\"\n multiple\n accept={acceptedFileTypes.join(',')}\n onChange={handleFileSelect}\n className=\"hidden\"\n />\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n className=\"h-10 w-10\"\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n fileInputRef.current?.click();\n }}\n disabled={disabled}\n >\n <Paperclip className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>{config?.labels?.attachFileTooltip}</TooltipContent>\n </Tooltip>\n </>\n )}\n\n {/* Text input */}\n <div className=\"relative flex-1\">\n <Textarea\n ref={textareaRef}\n value={value}\n onChange={(e) => {\n onChange(e.target.value);\n syncMentionState(e.target.value, e.target.selectionStart ?? e.target.value.length);\n }}\n onSelect={(e) => {\n const target = e.target as HTMLTextAreaElement;\n syncMentionState(target.value, target.selectionStart ?? target.value.length);\n }}\n onClick={(e) => {\n const target = e.target as HTMLTextAreaElement;\n syncMentionState(target.value, target.selectionStart ?? target.value.length);\n }}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n disabled={disabled}\n className=\"max-h-[120px] resize-none border-0 bg-transparent focus-visible:ring-0 focus-visible:ring-offset-0\"\n rows={1}\n />\n {isMentionMenuOpen && (\n <div className=\"absolute bottom-full left-0 right-0 mb-2 overflow-hidden rounded-md border bg-popover shadow-md\">\n <div className=\"p-1\">\n {filteredMentionAgents.map((agent, index) => (\n <button\n key={agent.id}\n type=\"button\"\n className={`flex w-full items-center gap-2 rounded-sm px-3 py-2 text-left text-sm ${\n index === activeMentionIndex ? 'bg-accent text-accent-foreground' : 'hover:bg-accent/60'\n }`}\n onMouseDown={(mouseEvent) => {\n mouseEvent.preventDefault();\n selectMentionAgent(agent);\n }}\n >\n <span className=\"font-medium\">{agent.name}</span>\n {agent.description && (\n <span className=\"truncate text-xs text-muted-foreground\">\n {agent.description}\n </span>\n )}\n </button>\n ))}\n </div>\n </div>\n )}\n </div>\n\n {/* Audio recording / voice compose entry */}\n {enableAudioRecording && !isRecording && canAddMoreAttachments && !value.trim() && (\n voiceComposeEnabled ? (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n className=\"h-10 w-10\"\n onClick={() => {\n void startVoiceCapture();\n }}\n disabled={disabled || isGenerating}\n >\n <Mic className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>{config?.labels?.voiceEnter || config?.labels?.recordAudioTooltip}</TooltipContent>\n </Tooltip>\n ) : (\n <AudioRecorder\n isRecording={isRecording}\n onStartRecording={startRecording}\n onStopRecording={stopRecording}\n onCancel={cancelRecording}\n recordingDuration={recordingDuration}\n config={config}\n />\n )\n )}\n\n {/* Submit/Stop button */}\n {isGenerating ? (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n className=\"h-10 w-10\"\n onClick={onStopGeneration}\n >\n <Square className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>{config?.labels?.stopGenerationTooltip}</TooltipContent>\n </Tooltip>\n ) : (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n type=\"submit\"\n size=\"icon\"\n className=\"h-10 w-10\"\n disabled={disabled || (!value.trim() && attachments.length === 0)}\n >\n {disabled ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Send className=\"h-4 w-4\" />\n )}\n </Button>\n </TooltipTrigger>\n <TooltipContent>{config?.labels?.sendMessageTooltip}</TooltipContent>\n </Tooltip>\n )}\n </div>\n </form>\n )}\n\n {/* Help text */}\n <div className=\"text-[10px] text-muted-foreground text-center\">\n {window.innerWidth > 768 ? config?.labels?.inputHelpText : ''}\n\n {attachments.length > 0 && (\n <> • {attachments.length}/{maxAttachments} anexos</>\n )}\n {config?.labels?.footerLabel && (\n <> • {config.labels.footerLabel}</>\n )}\n </div>\n </div>\n </div>\n {/* </CardContent>\n </Card> */}\n </TooltipProvider >\n );\n});\n","import React, { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react';\nimport type { ChatUserContext } from '../../types/chatTypes';\n\ntype Setter = (next: Partial<ChatUserContext> | ((prev: ChatUserContext) => Partial<ChatUserContext>)) => void;\n\ninterface ChatUserContextValue {\n context: ChatUserContext;\n setContext: Setter;\n resetContext: () => void;\n}\n\nconst Ctx = createContext<ChatUserContextValue | undefined>(undefined);\n\nexport const ChatUserContextProvider: React.FC<{ children: React.ReactNode; initial?: Partial<ChatUserContext> }>\n = ({ children, initial }) => {\n const [ctx, setCtx] = useState<ChatUserContext>(() => ({\n updatedAt: Date.now(),\n ...(initial ?? {}),\n }));\n\n useEffect(() => {\n if (!initial) return;\n setCtx(prev => {\n const keys = Object.keys(initial) as (keyof typeof initial)[];\n const hasChanges = keys.some(k => prev[k] !== initial[k]);\n if (!hasChanges) return prev;\n return { ...prev, ...initial, updatedAt: Date.now() };\n });\n }, [initial]);\n\n const setPartial = useCallback<Setter>((next) => {\n setCtx(prev => {\n const partial = typeof next === 'function' ? next(prev) : next;\n return { ...prev, ...partial, updatedAt: Date.now() };\n });\n }, []);\n\n const value = useMemo<ChatUserContextValue>(() => ({\n context: ctx,\n setContext: setPartial,\n resetContext: () => setCtx({ updatedAt: Date.now() })\n }), [ctx, setPartial]);\n\n return <Ctx.Provider value={value}>{children}</Ctx.Provider>;\n};\n\nexport function useChatUserContext(): ChatUserContextValue {\n const v = useContext(Ctx);\n if (!v) throw new Error('useChatUserContext must be used within ChatUserContextProvider');\n return v;\n}\n","import type {\n AudioAttachment,\n CreateVoiceProvider,\n VoiceProvider,\n VoiceProviderHandlers,\n VoiceProviderOptions,\n VoiceSegment,\n VoiceTranscript,\n} from '../types/chatTypes';\n\nconst AUDIO_MIME_TYPES = [\n 'audio/webm;codecs=opus',\n 'audio/webm',\n 'audio/mp4',\n 'audio/ogg;codecs=opus',\n];\n\nconst pickRecorderMimeType = (): string | undefined => {\n if (typeof MediaRecorder === 'undefined') return undefined;\n\n for (const mimeType of AUDIO_MIME_TYPES) {\n if (typeof MediaRecorder.isTypeSupported === 'function' && MediaRecorder.isTypeSupported(mimeType)) {\n return mimeType;\n }\n }\n\n return undefined;\n};\n\nconst blobToDataUrl = (blob: Blob): Promise<string> =>\n new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result as string);\n reader.onerror = () => reject(reader.error ?? new Error('Failed to read recorded audio'));\n reader.readAsDataURL(blob);\n });\n\nconst joinTranscriptParts = (...parts: Array<string | undefined>): string | undefined => {\n const value = parts\n .map((part) => part?.trim())\n .filter((part): part is string => Boolean(part && part.length > 0))\n .join(' ')\n .trim();\n\n return value.length > 0 ? value : undefined;\n};\n\nconst getAudioContextCtor = (): typeof AudioContext | undefined =>\n globalThis.AudioContext ||\n (globalThis as typeof globalThis & { webkitAudioContext?: typeof AudioContext }).webkitAudioContext;\n\nconst getOfflineAudioContextCtor = (): typeof OfflineAudioContext | undefined =>\n globalThis.OfflineAudioContext ||\n (globalThis as typeof globalThis & { webkitOfflineAudioContext?: typeof OfflineAudioContext }).webkitOfflineAudioContext;\n\nconst attachmentToArrayBuffer = async (attachment: AudioAttachment): Promise<ArrayBuffer> => {\n const response = await fetch(attachment.dataUrl);\n return response.arrayBuffer();\n};\n\nconst decodeAudioAttachment = async (attachment: AudioAttachment): Promise<AudioBuffer> => {\n const AudioContextCtor = getAudioContextCtor();\n if (!AudioContextCtor) {\n throw new Error('Audio decoding is not supported in this browser');\n }\n\n const audioContext = new AudioContextCtor();\n\n try {\n const arrayBuffer = await attachmentToArrayBuffer(attachment);\n return await audioContext.decodeAudioData(arrayBuffer.slice(0));\n } finally {\n await closeAudioContext(audioContext);\n }\n};\n\nconst renderMergedBuffer = async (buffers: AudioBuffer[]): Promise<AudioBuffer> => {\n const OfflineAudioContextCtor = getOfflineAudioContextCtor();\n if (!OfflineAudioContextCtor) {\n throw new Error('Offline audio rendering is not supported in this browser');\n }\n\n const numberOfChannels = Math.max(...buffers.map((buffer) => buffer.numberOfChannels));\n const sampleRate = Math.max(...buffers.map((buffer) => buffer.sampleRate));\n const totalFrames = Math.max(1, Math.ceil(buffers.reduce((sum, buffer) => sum + (buffer.duration * sampleRate), 0)));\n const offlineContext = new OfflineAudioContextCtor(numberOfChannels, totalFrames, sampleRate);\n\n let offsetSeconds = 0;\n for (const buffer of buffers) {\n const source = offlineContext.createBufferSource();\n source.buffer = buffer;\n source.connect(offlineContext.destination);\n source.start(offsetSeconds);\n offsetSeconds += buffer.duration;\n }\n\n return offlineContext.startRendering();\n};\n\nconst encodeWav = (audioBuffer: AudioBuffer): Blob => {\n const numberOfChannels = audioBuffer.numberOfChannels;\n const sampleRate = audioBuffer.sampleRate;\n const bitsPerSample = 16;\n const bytesPerSample = bitsPerSample / 8;\n const dataLength = audioBuffer.length * numberOfChannels * bytesPerSample;\n const buffer = new ArrayBuffer(44 + dataLength);\n const view = new DataView(buffer);\n\n const writeString = (offset: number, value: string) => {\n for (let index = 0; index < value.length; index += 1) {\n view.setUint8(offset + index, value.charCodeAt(index));\n }\n };\n\n writeString(0, 'RIFF');\n view.setUint32(4, 36 + dataLength, true);\n writeString(8, 'WAVE');\n writeString(12, 'fmt ');\n view.setUint32(16, 16, true);\n view.setUint16(20, 1, true);\n view.setUint16(22, numberOfChannels, true);\n view.setUint32(24, sampleRate, true);\n view.setUint32(28, sampleRate * numberOfChannels * bytesPerSample, true);\n view.setUint16(32, numberOfChannels * bytesPerSample, true);\n view.setUint16(34, bitsPerSample, true);\n writeString(36, 'data');\n view.setUint32(40, dataLength, true);\n\n let offset = 44;\n const channelData = Array.from({ length: numberOfChannels }, (_, index) => audioBuffer.getChannelData(index));\n\n for (let sampleIndex = 0; sampleIndex < audioBuffer.length; sampleIndex += 1) {\n for (let channelIndex = 0; channelIndex < numberOfChannels; channelIndex += 1) {\n const sample = Math.max(-1, Math.min(1, channelData[channelIndex][sampleIndex]));\n const pcmValue = sample < 0 ? sample * 0x8000 : sample * 0x7fff;\n view.setInt16(offset, pcmValue, true);\n offset += 2;\n }\n }\n\n return new Blob([buffer], { type: 'audio/wav' });\n};\n\nconst resolveSegmentCount = (segment?: VoiceSegment | null): number => {\n const candidate = segment?.metadata?.segmentCount;\n return typeof candidate === 'number' && Number.isFinite(candidate) && candidate > 0 ? candidate : (segment ? 1 : 0);\n};\n\nexport const mergeVoiceTranscripts = (\n previous?: VoiceTranscript,\n incoming?: VoiceTranscript,\n): VoiceTranscript => ({\n final: joinTranscriptParts(previous?.final, incoming?.final),\n partial: joinTranscriptParts(previous?.final, incoming?.partial),\n});\n\nexport const appendVoiceSegments = async (\n previous: VoiceSegment,\n incoming: VoiceSegment,\n): Promise<VoiceSegment> => {\n const [previousBuffer, incomingBuffer] = await Promise.all([\n decodeAudioAttachment(previous.attachment),\n decodeAudioAttachment(incoming.attachment),\n ]);\n const mergedBuffer = await renderMergedBuffer([previousBuffer, incomingBuffer]);\n const mergedBlob = encodeWav(mergedBuffer);\n const dataUrl = await blobToDataUrl(mergedBlob);\n const segmentCount = resolveSegmentCount(previous) + resolveSegmentCount(incoming);\n\n return {\n attachment: {\n kind: 'audio',\n dataUrl,\n mimeType: mergedBlob.type,\n durationMs: Math.round(mergedBuffer.duration * 1000),\n fileName: `voice-${new Date().toISOString().replace(/[:.]/g, '-')}.wav`,\n size: mergedBlob.size,\n },\n transcript: mergeVoiceTranscripts(previous.transcript, incoming.transcript),\n metadata: {\n ...previous.metadata,\n ...incoming.metadata,\n segmentCount,\n source: segmentCount > 1 ? 'merged' : (incoming.metadata?.source ?? previous.metadata?.source),\n },\n };\n};\n\nconst stopStream = (stream: MediaStream | null) => {\n if (!stream) return;\n stream.getTracks().forEach((track) => track.stop());\n};\n\nconst closeAudioContext = async (audioContext: AudioContext | null) => {\n if (!audioContext) return;\n\n try {\n await audioContext.close();\n } catch {\n // Ignore close errors from partially-initialized contexts.\n }\n};\n\nconst emitDuration = (handlers: VoiceProviderHandlers, startedAt: number) => {\n handlers.onDurationChange?.(Math.max(0, Date.now() - startedAt));\n};\n\nexport const createManualVoiceProvider: CreateVoiceProvider = async (\n handlers,\n options = {},\n): Promise<VoiceProvider> => {\n let mediaRecorder: MediaRecorder | null = null;\n let mediaStream: MediaStream | null = null;\n let audioContext: AudioContext | null = null;\n let analyser: AnalyserNode | null = null;\n let levelData: Uint8Array | null = null;\n let levelFrame = 0;\n let durationTimer: ReturnType<typeof setInterval> | null = null;\n let maxDurationTimer: ReturnType<typeof setTimeout> | null = null;\n let startedAt = 0;\n let shouldEmitSegment = true;\n let isStarting = false;\n\n const clearTimers = () => {\n if (durationTimer) {\n clearInterval(durationTimer);\n durationTimer = null;\n }\n if (maxDurationTimer) {\n clearTimeout(maxDurationTimer);\n maxDurationTimer = null;\n }\n };\n\n const stopLevelLoop = () => {\n if (levelFrame) {\n cancelAnimationFrame(levelFrame);\n levelFrame = 0;\n }\n handlers.onAudioLevelChange?.(0);\n };\n\n const startLevelLoop = () => {\n if (!analyser || !levelData) return;\n\n const tick = () => {\n if (!analyser || !levelData) return;\n\n analyser.getByteTimeDomainData(levelData);\n let sum = 0;\n for (let index = 0; index < levelData.length; index += 1) {\n const centered = (levelData[index] - 128) / 128;\n sum += centered * centered;\n }\n\n const rms = Math.sqrt(sum / levelData.length);\n handlers.onAudioLevelChange?.(Math.min(1, rms * 4));\n levelFrame = requestAnimationFrame(tick);\n };\n\n tick();\n };\n\n const cleanupActiveResources = async () => {\n clearTimers();\n stopLevelLoop();\n stopStream(mediaStream);\n mediaStream = null;\n analyser = null;\n levelData = null;\n await closeAudioContext(audioContext);\n audioContext = null;\n };\n\n const finalizeStop = async () => {\n mediaRecorder = null;\n isStarting = false;\n await cleanupActiveResources();\n };\n\n const start = async () => {\n if (isStarting || mediaRecorder?.state === 'recording') {\n return;\n }\n\n if (!navigator.mediaDevices?.getUserMedia) {\n throw new Error('Audio capture is not supported in this browser');\n }\n\n if (typeof MediaRecorder === 'undefined') {\n throw new Error('MediaRecorder is not supported in this browser');\n }\n\n isStarting = true;\n shouldEmitSegment = true;\n handlers.onTranscriptChange?.({});\n handlers.onDurationChange?.(0);\n handlers.onAudioLevelChange?.(0);\n handlers.onStateChange?.('preparing');\n\n try {\n mediaStream = await navigator.mediaDevices.getUserMedia({ audio: true });\n const mimeType = pickRecorderMimeType();\n mediaRecorder = mimeType\n ? new MediaRecorder(mediaStream, { mimeType })\n : new MediaRecorder(mediaStream);\n\n const chunks: BlobPart[] = [];\n\n mediaRecorder.ondataavailable = (event) => {\n if (event.data.size > 0) {\n chunks.push(event.data);\n }\n };\n\n mediaRecorder.onerror = (event) => {\n const error = event.error ?? new Error('Audio recorder failed');\n handlers.onError?.(error);\n };\n\n mediaRecorder.onstop = async () => {\n const durationMs = startedAt > 0 ? Math.max(0, Date.now() - startedAt) : 0;\n\n try {\n if (shouldEmitSegment && chunks.length > 0) {\n const blob = new Blob(chunks, {\n type: mediaRecorder?.mimeType || mimeType || 'audio/webm',\n });\n const dataUrl = await blobToDataUrl(blob);\n\n handlers.onSegmentReady?.({\n attachment: {\n kind: 'audio',\n dataUrl,\n mimeType: blob.type || 'audio/webm',\n durationMs,\n fileName: `voice-${new Date().toISOString().replace(/[:.]/g, '-')}.webm`,\n size: blob.size,\n },\n metadata: { source: 'manual', segmentCount: 1 },\n });\n } else {\n handlers.onStateChange?.('idle');\n }\n } catch (error) {\n handlers.onError?.(error as Error);\n } finally {\n await finalizeStop();\n }\n };\n\n const AudioContextCtor = globalThis.AudioContext ||\n (globalThis as typeof globalThis & { webkitAudioContext?: typeof AudioContext }).webkitAudioContext;\n\n if (AudioContextCtor) {\n audioContext = new AudioContextCtor();\n await audioContext.resume().catch(() => undefined);\n const sourceNode = audioContext.createMediaStreamSource(mediaStream);\n analyser = audioContext.createAnalyser();\n analyser.fftSize = 1024;\n levelData = new Uint8Array(analyser.fftSize);\n sourceNode.connect(analyser);\n startLevelLoop();\n }\n\n startedAt = Date.now();\n emitDuration(handlers, startedAt);\n durationTimer = setInterval(() => emitDuration(handlers, startedAt), 200);\n if (options.maxRecordingMs && options.maxRecordingMs > 0) {\n maxDurationTimer = setTimeout(() => {\n void stop();\n }, options.maxRecordingMs);\n }\n\n mediaRecorder.start();\n handlers.onStateChange?.('listening');\n } catch (error) {\n isStarting = false;\n await cleanupActiveResources();\n throw error;\n }\n };\n\n const stop = async () => {\n if (!mediaRecorder || mediaRecorder.state === 'inactive') {\n return;\n }\n\n handlers.onStateChange?.('finishing');\n mediaRecorder.stop();\n };\n\n const cancel = async () => {\n shouldEmitSegment = false;\n\n if (mediaRecorder && mediaRecorder.state !== 'inactive') {\n mediaRecorder.stop();\n return;\n }\n\n await finalizeStop();\n handlers.onStateChange?.('idle');\n };\n\n const destroy = async () => {\n await cancel();\n };\n\n return {\n start,\n stop,\n cancel,\n destroy,\n };\n};\n\nexport const resolveVoiceProviderFactory = (\n createProvider?: CreateVoiceProvider,\n): CreateVoiceProvider => createProvider ?? createManualVoiceProvider;\n","import * as React from \"react\"\nimport * as ProgressPrimitive from \"@radix-ui/react-progress\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Progress({\n className,\n value,\n ...props\n}: React.ComponentProps<typeof ProgressPrimitive.Root>) {\n return (\n <ProgressPrimitive.Root\n data-slot=\"progress\"\n className={cn(\n \"bg-primary/20 relative h-2 w-full overflow-hidden rounded-full\",\n className\n )}\n {...props}\n >\n <ProgressPrimitive.Indicator\n data-slot=\"progress-indicator\"\n className=\"bg-primary h-full w-full flex-1 transition-all\"\n style={{ transform: `translateX(-${100 - (value || 0)}%)` }}\n />\n </ProgressPrimitive.Root>\n )\n}\n\nexport { Progress }\n","import React from 'react';\nimport type { AudioAttachment, ChatConfig, VoiceComposerState, VoiceReviewMode, VoiceTranscript, VoiceTranscriptMode } from '../../types/chatTypes';\nimport { Button } from '../ui/button';\nimport { Progress } from '../ui/progress';\nimport { Badge } from '../ui/badge';\nimport { Keyboard, Loader2, Mic, Send, Square, Trash2, X } from 'lucide-react';\n\ninterface VoiceComposerProps {\n state: VoiceComposerState;\n transcript?: VoiceTranscript;\n transcriptMode: VoiceTranscriptMode;\n showTranscriptPreview: boolean;\n attachment?: AudioAttachment | null;\n durationMs: number;\n audioLevel: number;\n countdownMs: number;\n autoSendDelayMs: number;\n isAutoSendActive: boolean;\n reviewMode: VoiceReviewMode;\n errorMessage?: string | null;\n disabled?: boolean;\n labels?: ChatConfig['labels'];\n onStart: () => void;\n onStop: () => void;\n onPauseReview: () => void;\n onCancelAutoSend: () => void;\n onDiscard: () => void;\n onRecordAgain: () => void;\n onSendNow: () => void;\n onExit: () => void;\n}\n\nconst formatDuration = (durationMs: number): string => {\n const totalSeconds = Math.max(0, Math.floor(durationMs / 1000));\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n return `${minutes}:${seconds.toString().padStart(2, '0')}`;\n};\n\nconst interpolateSeconds = (label: string | undefined, seconds: number): string => {\n if (!label) {\n return `Auto-sends in ${seconds}s`;\n }\n\n if (label.includes('{{seconds}}')) {\n return label.replace(/\\{\\{\\s*seconds\\s*\\}\\}/g, String(seconds));\n }\n\n return `${label} ${seconds}s`;\n};\n\nconst resolveStateLabel = (state: VoiceComposerState, labels?: ChatConfig['labels'], errorMessage?: string | null): string => {\n switch (state) {\n case 'preparing':\n return labels?.voicePreparing || 'Preparing microphone...';\n case 'waiting_for_speech':\n return labels?.voiceWaiting || 'Waiting for speech...';\n case 'listening':\n return labels?.voiceListening || 'Listening...';\n case 'finishing':\n return labels?.voiceFinishing || 'Finishing capture...';\n case 'review':\n return labels?.voiceReview || 'Ready to send';\n case 'sending':\n return labels?.voiceSending || 'Sending...';\n case 'error':\n return errorMessage || labels?.voiceCaptureError || 'Unable to capture audio.';\n case 'idle':\n default:\n return labels?.voiceIdle || 'Tap the mic to record';\n }\n};\n\nconst resolveTranscriptText = (\n transcript: VoiceTranscript | undefined,\n transcriptMode: VoiceTranscriptMode,\n): string | null => {\n if (transcriptMode === 'none' || !transcript) {\n return null;\n }\n\n if (transcriptMode === 'final-only') {\n return transcript.final?.trim() || null;\n }\n\n return transcript.final?.trim() || transcript.partial?.trim() || null;\n};\n\nexport const VoiceComposer: React.FC<VoiceComposerProps> = ({\n state,\n transcript,\n transcriptMode,\n showTranscriptPreview,\n attachment,\n durationMs,\n audioLevel,\n countdownMs,\n autoSendDelayMs,\n isAutoSendActive,\n reviewMode,\n errorMessage,\n disabled = false,\n labels,\n onStart,\n onStop,\n onPauseReview,\n onCancelAutoSend,\n onDiscard,\n onRecordAgain,\n onSendNow,\n onExit,\n}) => {\n const transcriptText = resolveTranscriptText(transcript, transcriptMode);\n const countdownSeconds = Math.max(1, Math.ceil(countdownMs / 1000));\n const isBusy = state === 'preparing' || state === 'finishing' || state === 'sending';\n const isCapturing = state === 'waiting_for_speech' || state === 'listening';\n const hasDraft = Boolean(attachment);\n const isDraftLayout = hasDraft;\n const isArmedDraft = isDraftLayout && reviewMode === 'armed' && (\n state === 'waiting_for_speech' || state === 'listening'\n );\n const draftStatusLabel = state === 'listening'\n ? (labels?.voiceListening || 'Listening...')\n : state === 'waiting_for_speech'\n ? (labels?.voiceWaiting || 'Waiting for speech...')\n : state === 'finishing'\n ? (labels?.voiceFinishing || 'Finishing capture...')\n : state === 'sending'\n ? (labels?.voiceSending || 'Sending...')\n : (labels?.voiceReview || 'Ready to send');\n const levelValue = isCapturing || state === 'preparing' || state === 'finishing'\n ? Math.max(8, Math.round(audioLevel * 100))\n : 0;\n const headerLabel = hasDraft && state !== 'sending' && state !== 'error'\n ? draftStatusLabel\n : state === 'error'\n ? (labels?.voiceCaptureError || 'Unable to capture audio.')\n : resolveStateLabel(state, labels, errorMessage);\n const reviewHelperText = isArmedDraft\n ? (labels?.voiceReviewArmedHint || 'Speak to add more before it sends.')\n : (labels?.voiceReviewPausedHint || labels?.voiceRecordAgain || 'Tap the mic to continue this message.');\n const orbIsListening = state === 'listening';\n const orbCanStop = !isDraftLayout && (state === 'waiting_for_speech' || state === 'listening');\n const orbIsReviewBusy = state === 'preparing' || state === 'finishing' || state === 'sending';\n const handleReviewOrbClick = () => {\n if (state === 'listening') {\n onStop();\n return;\n }\n\n if (isArmedDraft) {\n onPauseReview();\n return;\n }\n\n onRecordAgain();\n };\n\n return (\n <div className=\"w-full max-w-3xl rounded-2xl border bg-background p-3 shadow-sm sm:p-4 md:min-w-3xl\">\n <div className=\"flex items-center justify-between gap-2 sm:gap-3\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <Badge variant=\"outline\">{labels?.voiceTitle || 'Voice'}</Badge>\n <span className=\"truncate rounded-full bg-muted px-2.5 py-1 text-[11px] sm:text-xs text-muted-foreground\">\n {headerLabel}\n </span>\n </div>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"shrink-0 px-2 sm:px-3\"\n onClick={onExit}\n disabled={disabled || isBusy}\n >\n <Keyboard className=\"h-4 w-4\" />\n <span className=\"hidden sm:inline\">{labels?.voiceExit || 'Use keyboard'}</span>\n </Button>\n </div>\n\n {!isDraftLayout ? (\n <div className=\"mt-3 rounded-xl border border-dashed border-primary/30 bg-primary/5 px-3 py-3 text-center sm:px-4 sm:py-4\">\n <div className=\"mx-auto flex w-full max-w-sm flex-col items-center gap-3\">\n <Button\n type=\"button\"\n size=\"icon\"\n variant={isCapturing ? 'destructive' : 'outline'}\n className={`h-16 w-16 rounded-full sm:h-20 sm:w-20 ${isCapturing ? 'bg-red-500 hover:bg-red-600 text-white border-red-500' : 'border-red-200 bg-red-50 text-red-600 hover:bg-red-100 hover:text-red-700'}`}\n onClick={isCapturing ? onStop : onStart}\n disabled={disabled || isBusy}\n >\n {isBusy ? (\n <Loader2 className=\"h-7 w-7 animate-spin\" />\n ) : isCapturing ? (\n <Square className=\"h-7 w-7\" />\n ) : (\n <Mic className=\"h-7 w-7\" />\n )}\n </Button>\n\n <div className=\"w-full space-y-2\">\n <Progress value={levelValue} className=\"h-2\" />\n <div className=\"flex items-center justify-between text-xs text-muted-foreground\">\n <span>{formatDuration(durationMs)}</span>\n <span>{isCapturing ? (labels?.voiceStop || 'Stop recording') : (labels?.voiceStart || 'Start recording')}</span>\n </div>\n </div>\n\n {showTranscriptPreview && transcriptMode !== 'none' && transcriptText && (\n <div className=\"w-full rounded-lg border bg-background px-3 py-2 text-left text-sm\">\n {transcriptText}\n </div>\n )}\n </div>\n </div>\n ) : (\n <div className=\"mt-3 rounded-xl border bg-muted/20 p-3 sm:p-4\">\n <div className=\"flex items-center justify-between gap-2 text-xs text-muted-foreground\">\n <span>{formatDuration(durationMs)}</span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8 shrink-0 text-muted-foreground hover:text-destructive\"\n onClick={onDiscard}\n disabled={disabled}\n aria-label={labels?.voiceDiscard || 'Delete recording'}\n title={labels?.voiceDiscard || 'Delete recording'}\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </div>\n\n <div className=\"mt-4 flex flex-col items-center gap-4 text-center\">\n <Button\n type=\"button\"\n size=\"icon\"\n variant={orbCanStop ? 'destructive' : 'outline'}\n className={`h-20 w-20 rounded-full sm:h-24 sm:w-24 ${\n orbIsListening\n ? 'border-red-500 bg-red-500 text-white hover:bg-red-600'\n : isArmedDraft\n ? 'border-red-200 bg-red-50 text-red-600 shadow-[0_0_0_10px_rgba(239,68,68,0.08)] hover:bg-red-100 hover:text-red-700'\n : 'border-red-200 bg-red-50 text-red-600 hover:bg-red-100 hover:text-red-700'\n }`}\n onClick={handleReviewOrbClick}\n disabled={disabled || orbIsReviewBusy}\n >\n {orbIsReviewBusy ? (\n <Loader2 className=\"h-7 w-7 animate-spin\" />\n ) : orbIsListening ? (\n <Square className=\"h-7 w-7\" />\n ) : isArmedDraft ? (\n <Mic className=\"h-7 w-7 animate-pulse\" />\n ) : (\n <Mic className=\"h-7 w-7\" />\n )}\n </Button>\n\n <div className=\"max-w-sm space-y-1 px-2\">\n <p className=\"text-sm text-foreground\">{reviewHelperText}</p>\n {isCapturing && (\n <div className=\"mx-auto h-1.5 w-32 overflow-hidden rounded-full bg-red-100\">\n <div\n className=\"h-full rounded-full bg-red-500 transition-[width] duration-150\"\n style={{ width: `${levelValue}%` }}\n />\n </div>\n )}\n </div>\n </div>\n\n {attachment && (\n <div className=\"mt-4 rounded-lg border bg-background/90 p-2 shadow-sm\">\n <audio controls preload=\"metadata\" className=\"w-full\">\n <source src={attachment.dataUrl} type={attachment.mimeType} />\n </audio>\n </div>\n )}\n\n {showTranscriptPreview && transcriptMode !== 'none' && transcriptText && (\n <div className=\"mt-3 rounded-lg border bg-background px-3 py-2 text-left text-sm\">\n {transcriptText}\n </div>\n )}\n\n {isAutoSendActive && autoSendDelayMs > 0 && (\n <div className=\"mt-3 flex justify-center\">\n <div className=\"inline-flex items-center rounded-full border bg-background px-3 py-1 text-xs text-muted-foreground\">\n {interpolateSeconds(labels?.voiceAutoSendIn, countdownSeconds)}\n </div>\n </div>\n )}\n\n <div className=\"mt-4 grid grid-cols-1 gap-2 sm:flex sm:items-center sm:justify-end\">\n {isAutoSendActive && (\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" onClick={onCancelAutoSend} disabled={disabled} className=\"w-full sm:w-auto\">\n <X className=\"h-4 w-4\" />\n {labels?.voiceCancel || 'Cancel'}\n </Button>\n )}\n <Button type=\"button\" size=\"sm\" onClick={onSendNow} disabled={disabled} className=\"w-full sm:w-auto\">\n <Send className=\"h-4 w-4\" />\n {labels?.voiceSendNow || 'Send now'}\n </Button>\n </div>\n </div>\n )}\n\n {errorMessage && (\n <div className=\"mt-3 rounded-lg border border-destructive/30 bg-destructive/5 px-3 py-2 text-sm text-destructive\">\n {errorMessage}\n </div>\n )}\n </div>\n );\n};\n","import React, { useState } from 'react';\nimport { Sheet, SheetContent, SheetHeader, SheetTitle } from '../ui/sheet';\nimport { Avatar, AvatarFallback, AvatarImage } from '../ui/avatar';\nimport { ScrollArea } from '../ui/scroll-area';\nimport { Button } from '../ui/button';\nimport { Separator } from '../ui/separator';\nimport { Input } from '../ui/input';\nimport { Textarea } from '../ui/textarea';\nimport { cn } from '../../lib/utils';\nimport {\n User,\n Mail,\n AtSign,\n Calendar,\n MapPin,\n Phone,\n Globe,\n Building,\n Briefcase,\n Users,\n UserPlus,\n Image,\n BadgeCheck,\n FileText,\n Brain,\n Plus,\n Trash2,\n Target,\n Lightbulb,\n Info,\n Heart,\n Bot,\n Pencil,\n Check,\n X,\n} from 'lucide-react';\nimport type { MemoryItem } from '../../types/chatTypes';\n\nexport interface UserProfileConfig {\n labels?: {\n title?: string;\n basicInfo?: string;\n customFields?: string;\n memories?: string;\n addMemory?: string;\n noMemories?: string;\n close?: string;\n noCustomFields?: string;\n };\n}\n\nexport interface UserProfileUser {\n id: string;\n name?: string;\n email?: string;\n avatar?: string;\n}\n\n// Custom field definition - can be extended by login/external components\nexport interface CustomField {\n key: string;\n label: string;\n value: string | number | boolean | null | undefined;\n type?: 'text' | 'email' | 'phone' | 'url' | 'date' | 'number' | 'boolean';\n icon?: React.ReactNode;\n}\n\nexport interface UserProfileProps {\n isOpen: boolean;\n onClose: () => void;\n user?: UserProfileUser | null;\n /** Custom fields from userContext.customFields */\n customFields?: CustomField[] | Record<string, unknown>;\n /** User memories */\n memories?: MemoryItem[];\n config?: UserProfileConfig;\n /** Called when user wants to edit their profile */\n onEditProfile?: () => void;\n /** Called when user wants to logout */\n onLogout?: () => void;\n /** Called when user adds a memory */\n onAddMemory?: (content: string, category?: MemoryItem['category']) => void;\n /** Called when user updates a memory */\n onUpdateMemory?: (memoryId: string, content: string) => void;\n /** Called when user deletes a memory */\n onDeleteMemory?: (memoryId: string) => void;\n className?: string;\n}\n\n// Get initials from name or email\nconst getInitials = (name?: string, email?: string): string => {\n if (name) {\n return name\n .split(' ')\n .map((n) => n[0])\n .slice(0, 2)\n .join('')\n .toUpperCase();\n }\n if (email) {\n return email[0].toUpperCase();\n }\n return 'U';\n};\n\n// Map field types to icons\nconst getFieldIcon = (type?: string, key?: string): React.ReactNode => {\n const iconClass = 'h-4 w-4 text-muted-foreground';\n \n // Check by type first\n switch (type) {\n case 'email':\n return <Mail className={iconClass} />;\n case 'phone':\n return <Phone className={iconClass} />;\n case 'url':\n return <Globe className={iconClass} />;\n case 'date':\n return <Calendar className={iconClass} />;\n }\n \n // Check by common key names\n const lowerKey = key?.toLowerCase() || '';\n \n if (lowerKey.includes('follower')) return <Users className={iconClass} />;\n if (lowerKey.includes('following')) return <UserPlus className={iconClass} />;\n if (lowerKey.includes('post') || lowerKey.includes('publication')) return <Image className={iconClass} />;\n if (lowerKey.includes('verified') || lowerKey.includes('badge')) return <BadgeCheck className={iconClass} />;\n if (lowerKey.includes('bio')) return <FileText className={iconClass} />;\n \n // General fields\n if (lowerKey.includes('email')) return <Mail className={iconClass} />;\n if (lowerKey.includes('phone') || lowerKey.includes('tel')) return <Phone className={iconClass} />;\n if (lowerKey.includes('location') || lowerKey.includes('address') || lowerKey.includes('city')) return <MapPin className={iconClass} />;\n if (lowerKey.includes('company') || lowerKey.includes('org')) return <Building className={iconClass} />;\n if (lowerKey.includes('job') || lowerKey.includes('role') || lowerKey.includes('title') || lowerKey.includes('position')) return <Briefcase className={iconClass} />;\n if (lowerKey.includes('website') || lowerKey.includes('url') || lowerKey.includes('link')) return <Globe className={iconClass} />;\n if (lowerKey.includes('username') || lowerKey.includes('handle')) return <AtSign className={iconClass} />;\n if (lowerKey.includes('date') || lowerKey.includes('birthday') || lowerKey.includes('joined')) return <Calendar className={iconClass} />;\n \n return <User className={iconClass} />;\n};\n\n// Format value for display\nconst formatValue = (value: unknown, type?: string, key?: string): string => {\n if (value === null || value === undefined) return '-';\n if (typeof value === 'boolean') {\n if (key?.toLowerCase().includes('verified')) {\n return value ? 'Verified ✓' : 'Not verified';\n }\n return value ? 'Yes' : 'No';\n }\n if (type === 'date' && (typeof value === 'string' || typeof value === 'number')) {\n try {\n return new Date(value).toLocaleDateString('en-US');\n } catch {\n return String(value);\n }\n }\n return String(value);\n};\n\n// Convert Record<string, unknown> to CustomField[]\nconst normalizeCustomFields = (fields?: CustomField[] | Record<string, unknown>): CustomField[] => {\n if (!fields) return [];\n \n if (Array.isArray(fields)) {\n return fields;\n }\n \n // Convert object to array of fields\n return Object.entries(fields)\n .filter(([_, value]) => value !== null && value !== undefined && value !== '')\n .map(([key, value]) => ({\n key,\n label: key\n .replace(/([A-Z])/g, ' $1')\n .replace(/[_-]/g, ' ')\n .replace(/^\\w/, (c) => c.toUpperCase())\n .trim(),\n value: value as string | number | boolean,\n }));\n};\n\n// Get icon for memory category\nconst getMemoryCategoryIcon = (category?: MemoryItem['category']): React.ReactNode => {\n const iconClass = 'h-4 w-4 text-muted-foreground';\n switch (category) {\n case 'preference':\n return <Heart className={iconClass} />;\n case 'fact':\n return <Info className={iconClass} />;\n case 'goal':\n return <Target className={iconClass} />;\n case 'context':\n return <Lightbulb className={iconClass} />;\n default:\n return <Brain className={iconClass} />;\n }\n};\n\n// Get label for memory category\nconst getMemoryCategoryLabel = (category?: MemoryItem['category']): string => {\n switch (category) {\n case 'preference':\n return 'Preferência';\n case 'fact':\n return 'Fato';\n case 'goal':\n return 'Meta';\n case 'context':\n return 'Contexto';\n default:\n return 'Outro';\n }\n};\n\nexport const UserProfile: React.FC<UserProfileProps> = ({\n isOpen,\n onClose,\n user,\n customFields,\n memories = [],\n config,\n onEditProfile,\n onLogout,\n onAddMemory,\n onUpdateMemory,\n onDeleteMemory,\n className,\n}) => {\n const [newMemoryContent, setNewMemoryContent] = useState('');\n const [isAddingMemory, setIsAddingMemory] = useState(false);\n const [editingMemoryId, setEditingMemoryId] = useState<string | null>(null);\n const [editingMemoryContent, setEditingMemoryContent] = useState('');\n\n const handleAddMemory = () => {\n if (newMemoryContent.trim() && onAddMemory) {\n onAddMemory(newMemoryContent.trim(), 'other');\n setNewMemoryContent('');\n setIsAddingMemory(false);\n }\n };\n\n const handleStartEdit = (memory: MemoryItem) => {\n setEditingMemoryId(memory.id);\n setEditingMemoryContent(memory.content);\n };\n\n const handleSaveEdit = () => {\n if (editingMemoryId && editingMemoryContent.trim() && onUpdateMemory) {\n onUpdateMemory(editingMemoryId, editingMemoryContent.trim());\n setEditingMemoryId(null);\n setEditingMemoryContent('');\n }\n };\n\n const handleCancelEdit = () => {\n setEditingMemoryId(null);\n setEditingMemoryContent('');\n };\n\n const labels = {\n title: config?.labels?.title || 'Profile',\n basicInfo: config?.labels?.basicInfo || 'Account',\n customFields: config?.labels?.customFields || 'Details',\n memories: config?.labels?.memories || 'Memories',\n addMemory: config?.labels?.addMemory || 'Add memory',\n noMemories: config?.labels?.noMemories || 'No memories yet',\n close: config?.labels?.close || 'Close',\n noCustomFields: config?.labels?.noCustomFields || 'No additional information',\n };\n\n const displayName = user?.name || user?.email?.split('@')[0] || 'User';\n const initials = getInitials(user?.name, user?.email);\n const normalizedFields = normalizeCustomFields(customFields);\n\n return (\n <Sheet open={isOpen} onOpenChange={(open) => !open && onClose()}>\n <SheetContent\n side=\"right\"\n className={cn('w-full sm:max-w-md p-0 flex flex-col h-full overflow-hidden', className)}\n >\n <SheetHeader className=\"px-6 py-4 border-b shrink-0\">\n <div className=\"flex items-center justify-between\">\n <SheetTitle>{labels.title}</SheetTitle>\n </div>\n </SheetHeader>\n\n <ScrollArea className=\"flex-1 min-h-0\">\n <div className=\"p-6 space-y-6\">\n {/* User header */}\n <div className=\"flex flex-col items-center text-center space-y-4\">\n <Avatar className=\"h-24 w-24 shrink-0\">\n {user?.avatar && <AvatarImage src={user.avatar} alt={displayName} />}\n <AvatarFallback className=\"text-2xl bg-primary/10 text-primary\">\n {initials}\n </AvatarFallback>\n </Avatar>\n <div className=\"w-full px-2\">\n <h2 className=\"text-xl font-semibold break-words\">{displayName}</h2>\n {user?.email && (\n <p className=\"text-sm text-muted-foreground break-words\">{user.email}</p>\n )}\n </div>\n </div>\n\n <Separator />\n\n {/* Basic info */}\n <div className=\"space-y-3\">\n <h3 className=\"text-sm font-medium text-muted-foreground uppercase tracking-wider\">\n {labels.basicInfo}\n </h3>\n <div className=\"space-y-2\">\n <div className=\"flex items-start gap-3 p-3 rounded-lg bg-muted/50\">\n <User className=\"h-4 w-4 text-muted-foreground mt-0.5 shrink-0\" />\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-xs text-muted-foreground\">Name</p>\n <p className=\"text-sm font-medium break-words\">{displayName}</p>\n </div>\n </div>\n {user?.email && (\n <div className=\"flex items-start gap-3 p-3 rounded-lg bg-muted/50\">\n <AtSign className=\"h-4 w-4 text-muted-foreground mt-0.5 shrink-0\" />\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-xs text-muted-foreground\">Handle</p>\n <p className=\"text-sm font-medium break-words\">{user.email}</p>\n </div>\n </div>\n )}\n {user?.id && user.id !== user?.name && user.id !== user?.email && (\n <div className=\"flex items-start gap-3 p-3 rounded-lg bg-muted/50\">\n <User className=\"h-4 w-4 text-muted-foreground mt-0.5 shrink-0\" />\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-xs text-muted-foreground\">ID</p>\n <p className=\"text-sm font-medium break-words\">{user.id}</p>\n </div>\n </div>\n )}\n </div>\n </div>\n\n {/* Custom fields */}\n {normalizedFields.length > 0 && (\n <>\n <Separator />\n <div className=\"space-y-3\">\n <h3 className=\"text-sm font-medium text-muted-foreground uppercase tracking-wider\">\n {labels.customFields}\n </h3>\n <div className=\"space-y-2\">\n {normalizedFields.map((field) => {\n const isBioField = field.key.toLowerCase().includes('bio');\n return (\n <div\n key={field.key}\n className=\"flex items-start gap-3 p-3 rounded-lg bg-muted/50\"\n >\n <div className=\"mt-0.5 shrink-0\">\n {field.icon || getFieldIcon(field.type, field.key)}\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-xs text-muted-foreground\">{field.label}</p>\n <p className={cn(\n \"text-sm font-medium\",\n isBioField ? \"whitespace-pre-wrap break-words\" : \"break-words\"\n )}>\n {formatValue(field.value, field.type, field.key)}\n </p>\n </div>\n </div>\n );\n })}\n </div>\n </div>\n </>\n )}\n\n {/* Memories section */}\n <Separator />\n <div className=\"space-y-3\">\n <div className=\"flex items-center justify-between\">\n <h3 className=\"text-sm font-medium text-muted-foreground uppercase tracking-wider flex items-center gap-2\">\n <Brain className=\"h-4 w-4\" />\n {labels.memories}\n </h3>\n {onAddMemory && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-7 px-2\"\n onClick={() => setIsAddingMemory(true)}\n >\n <Plus className=\"h-4 w-4\" />\n </Button>\n )}\n </div>\n\n {/* Add memory input */}\n {isAddingMemory && onAddMemory && (\n <div className=\"flex gap-2\">\n <Input\n value={newMemoryContent}\n onChange={(e) => setNewMemoryContent(e.target.value)}\n placeholder=\"O que devo lembrar?\"\n className=\"flex-1 h-9\"\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleAddMemory();\n if (e.key === 'Escape') {\n setIsAddingMemory(false);\n setNewMemoryContent('');\n }\n }}\n autoFocus\n />\n <Button size=\"sm\" onClick={handleAddMemory} disabled={!newMemoryContent.trim()}>\n Salvar\n </Button>\n </div>\n )}\n\n {/* Memory list */}\n <div className=\"space-y-2\">\n {memories.length === 0 ? (\n <p className=\"text-sm text-muted-foreground text-center py-4\">\n {labels.noMemories}\n </p>\n ) : (\n memories.map((memory) => {\n const isEditing = editingMemoryId === memory.id;\n \n return (\n <div\n key={memory.id}\n className=\"flex items-start gap-3 p-3 rounded-lg bg-muted/50 group\"\n >\n <div className=\"mt-0.5 shrink-0\">\n {memory.source === 'agent' ? (\n <Bot className=\"h-4 w-4 text-primary\" />\n ) : (\n getMemoryCategoryIcon(memory.category)\n )}\n </div>\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2 mb-0.5\">\n <span className=\"text-xs text-muted-foreground\">\n {getMemoryCategoryLabel(memory.category)}\n </span>\n <span className=\"text-xs text-muted-foreground\">•</span>\n <span className=\"text-xs text-muted-foreground\">\n {memory.source === 'agent' ? 'IA' : 'Você'}\n </span>\n </div>\n {isEditing ? (\n <div className=\"space-y-2\">\n <Textarea\n value={editingMemoryContent}\n onChange={(e) => setEditingMemoryContent(e.target.value)}\n className=\"min-h-[60px] text-sm resize-none\"\n autoFocus\n onKeyDown={(e) => {\n if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) {\n handleSaveEdit();\n }\n if (e.key === 'Escape') {\n handleCancelEdit();\n }\n }}\n />\n <div className=\"flex gap-1 justify-end\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-7 px-2\"\n onClick={handleCancelEdit}\n >\n <X className=\"h-3.5 w-3.5 mr-1\" />\n Cancelar\n </Button>\n <Button\n size=\"sm\"\n className=\"h-7 px-2\"\n onClick={handleSaveEdit}\n disabled={!editingMemoryContent.trim()}\n >\n <Check className=\"h-3.5 w-3.5 mr-1\" />\n Salvar\n </Button>\n </div>\n </div>\n ) : (\n <p className=\"text-sm break-words\">{memory.content}</p>\n )}\n </div>\n {!isEditing && (onUpdateMemory || onDeleteMemory) && (\n <div className=\"flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity shrink-0\">\n {onUpdateMemory && (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-7 w-7\"\n onClick={() => handleStartEdit(memory)}\n >\n <Pencil className=\"h-3.5 w-3.5 text-muted-foreground\" />\n </Button>\n )}\n {onDeleteMemory && (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-7 w-7\"\n onClick={() => onDeleteMemory(memory.id)}\n >\n <Trash2 className=\"h-3.5 w-3.5 text-destructive\" />\n </Button>\n )}\n </div>\n )}\n </div>\n );\n })\n )}\n </div>\n </div>\n </div>\n </ScrollArea>\n\n {/* Footer actions */}\n <div className=\"p-4 border-t space-y-2 shrink-0\">\n {onEditProfile && (\n <Button\n variant=\"outline\"\n className=\"w-full\"\n onClick={onEditProfile}\n >\n Edit Profile\n </Button>\n )}\n {onLogout && (\n <Button\n variant=\"destructive\"\n className=\"w-full\"\n onClick={onLogout}\n >\n Log out\n </Button>\n )}\n </div>\n </SheetContent>\n </Sheet>\n );\n};\n\nexport default UserProfile;\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as ScrollAreaPrimitive from \"@radix-ui/react-scroll-area\"\n\nimport { cn } from \"../../lib/utils\"\n\nconst ScrollArea = React.forwardRef<\n HTMLDivElement,\n React.ComponentProps<typeof ScrollAreaPrimitive.Root> & {\n viewportClassName?: string\n }\n>(({ className, children, viewportClassName, onScroll, onScrollCapture, ...props }, ref) => {\n return (\n <ScrollAreaPrimitive.Root\n data-slot=\"scroll-area\"\n className={cn(\"relative\", className)}\n {...props}\n >\n <ScrollAreaPrimitive.Viewport\n ref={ref as React.Ref<HTMLDivElement>}\n data-slot=\"scroll-area-viewport\"\n className={cn(\n \"focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1\",\n viewportClassName\n )}\n onScroll={onScroll as any}\n onScrollCapture={onScrollCapture as any}\n >\n {children}\n </ScrollAreaPrimitive.Viewport>\n <ScrollBar />\n <ScrollAreaPrimitive.Corner />\n </ScrollAreaPrimitive.Root>\n )\n})\nScrollArea.displayName = \"ScrollArea\"\n\nfunction ScrollBar({\n className,\n orientation = \"vertical\",\n ...props\n}: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {\n return (\n <ScrollAreaPrimitive.ScrollAreaScrollbar\n data-slot=\"scroll-area-scrollbar\"\n orientation={orientation}\n className={cn(\n \"flex touch-none p-px transition-colors select-none\",\n orientation === \"vertical\" &&\n \"h-full w-2.5 border-l border-l-transparent\",\n orientation === \"horizontal\" &&\n \"h-2.5 flex-col border-t border-t-transparent\",\n className\n )}\n {...props}\n >\n <ScrollAreaPrimitive.ScrollAreaThumb\n data-slot=\"scroll-area-thumb\"\n className=\"bg-border relative flex-1 rounded-full\"\n />\n </ScrollAreaPrimitive.ScrollAreaScrollbar>\n )\n}\n\nexport { ScrollArea, ScrollBar }\n","import React, { useState, useRef, useEffect } from 'react';\nimport { ChatThread, ChatConfig } from '../../types/chatTypes';\nimport { formatDate } from '../../lib/utils';\nimport { Button } from '../ui/button';\nimport { Input } from '../ui/input';\nimport { Card, CardContent, CardHeader, CardTitle } from '../ui/card';\nimport { Badge } from '../ui/badge';\nimport { ScrollArea } from '../ui/scroll-area';\nimport { Separator } from '../ui/separator';\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from '../ui/dialog';\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from '../ui/alert-dialog';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '../ui/dropdown-menu';\nimport { TooltipProvider } from '../ui/tooltip';\nimport {\n Plus,\n MessageSquare,\n MoreVertical,\n Edit2,\n Trash2,\n Archive,\n Search,\n Filter,\n Calendar,\n Hash,\n X,\n Check,\n} from 'lucide-react';\n\ninterface ThreadManagerProps {\n threads: ChatThread[];\n currentThreadId?: string | null;\n config?: ChatConfig;\n onCreateThread?: (title?: string) => void;\n onSelectThread?: (threadId: string) => void;\n onRenameThread?: (threadId: string, newTitle: string) => void;\n onDeleteThread?: (threadId: string) => void;\n onArchiveThread?: (threadId: string) => void;\n isOpen?: boolean;\n onClose?: () => void;\n className?: string;\n}\n\n// Individual thread item component\nconst ThreadItem: React.FC<{\n thread: ChatThread;\n isActive: boolean;\n config?: ChatConfig;\n onSelect: () => void;\n onRename: (newTitle: string) => void;\n onDelete: () => void;\n onArchive: () => void;\n}> = ({ thread, isActive, config, onSelect, onRename, onDelete, onArchive }) => {\n const [isEditing, setIsEditing] = useState(false);\n const [editTitle, setEditTitle] = useState(thread.title);\n const inputRef = useRef<HTMLInputElement>(null);\n\n useEffect(() => {\n if (isEditing && inputRef.current) {\n inputRef.current.focus();\n inputRef.current.select();\n }\n }, [isEditing]);\n\n const handleSaveEdit = () => {\n const trimmedTitle = editTitle.trim();\n if (trimmedTitle && trimmedTitle !== thread.title) {\n onRename(trimmedTitle);\n }\n setIsEditing(false);\n };\n\n const handleCancelEdit = () => {\n setEditTitle(thread.title);\n setIsEditing(false);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter') {\n handleSaveEdit();\n } else if (e.key === 'Escape') {\n handleCancelEdit();\n }\n };\n\n return (\n <Card className={`cursor-pointer transition-all duration-200 hover:shadow-md py-0 ${\n isActive ? 'ring-2 ring-primary bg-primary/5' : 'hover:bg-muted/50'\n }`}>\n <CardContent className=\"p-3 max-w-sm\">\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"flex-1 min-w-0\" onClick={onSelect}>\n {isEditing ? (\n <div className=\"flex items-center gap-2\">\n <Input\n ref={inputRef}\n value={editTitle}\n onChange={(e) => setEditTitle(e.target.value)}\n onKeyDown={handleKeyDown}\n onBlur={handleSaveEdit}\n className=\"h-8 text-sm\"\n placeholder={config?.labels?.threadNamePlaceholder || \"Conversation name\"}\n />\n <Button size=\"sm\" variant=\"ghost\" onClick={handleSaveEdit}>\n <Check className=\"h-3 w-3\" />\n </Button>\n <Button size=\"sm\" variant=\"ghost\" onClick={handleCancelEdit}>\n <X className=\"h-3 w-3\" />\n </Button>\n </div>\n ) : (\n <>\n <h4 className=\"font-medium text-sm truncate mb-1\">\n {thread.title}\n </h4>\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <div className=\"flex items-center gap-1\">\n <Hash className=\"h-3 w-3\" />\n {thread.messageCount} msgs\n </div>\n <Separator orientation=\"vertical\" className=\"h-3\" />\n <div className=\"flex items-center gap-1\">\n <Calendar className=\"h-3 w-3\" />\n {formatDate(thread.updatedAt, config?.labels)}\n </div>\n {thread.isArchived && (\n <>\n <Separator orientation=\"vertical\" className=\"h-3\" />\n <Badge variant=\"secondary\" className=\"text-xs\">\n <Archive className=\"h-2 w-2 mr-1\" />\n {config?.labels?.archiveThread || 'Archived'}\n </Badge>\n </>\n )}\n </div>\n </>\n )}\n </div>\n\n {!isEditing && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"ghost\" size=\"icon\" className=\"h-6 w-6 m-auto\">\n <MoreVertical className=\"h-3 w-3\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onClick={() => setIsEditing(true)}>\n <Edit2 className=\"h-4 w-4 mr-2\" />\n {config?.labels?.renameThread || 'Rename'}\n </DropdownMenuItem>\n <DropdownMenuItem onClick={onArchive}>\n <Archive className=\"h-4 w-4 mr-2\" />\n {thread.isArchived \n ? (config?.labels?.unarchiveThread || 'Unarchive')\n : (config?.labels?.archiveThread || 'Archive')}\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem onClick={onDelete} className=\"text-destructive\">\n <Trash2 className=\"h-4 w-4 mr-2\" />\n {config?.labels?.deleteThread || 'Delete'}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n </div>\n </CardContent>\n </Card>\n );\n};\n\n// Create thread dialog\nconst CreateThreadDialog: React.FC<{\n onCreateThread: (title?: string) => void;\n config?: ChatConfig;\n}> = ({ onCreateThread, config }) => {\n const [title, setTitle] = useState('');\n const [isOpen, setIsOpen] = useState(false);\n\n const handleCreate = () => {\n onCreateThread(title.trim() || undefined);\n setTitle('');\n setIsOpen(false);\n };\n\n return (\n <Dialog open={isOpen} onOpenChange={setIsOpen}>\n <DialogTrigger asChild>\n <Button variant=\"outline\" className=\"w-full\">\n <Plus className=\"h-4 w-4 mr-2\" />\n {config?.labels?.createNewThread || 'New Conversation'}\n </Button>\n </DialogTrigger>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>{config?.labels?.createNewThread || 'Create New Conversation'}</DialogTitle>\n <DialogDescription>\n Give your new conversation a name or leave blank to auto-generate one.\n </DialogDescription>\n </DialogHeader>\n <Input\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n placeholder={config?.labels?.threadNamePlaceholder || \"Conversation name (optional)\"}\n onKeyDown={(e) => e.key === 'Enter' && handleCreate()}\n autoFocus\n />\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => setIsOpen(false)}>\n {config?.labels?.cancel || 'Cancel'}\n </Button>\n <Button onClick={handleCreate}>\n {config?.labels?.create || 'Create'}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n};\n\nexport const ThreadManager: React.FC<ThreadManagerProps> = ({\n threads,\n currentThreadId,\n config,\n onCreateThread,\n onSelectThread,\n onRenameThread,\n onDeleteThread,\n onArchiveThread,\n isOpen = false,\n onClose,\n className = '',\n}) => {\n const [searchQuery, setSearchQuery] = useState('');\n const [showArchived, setShowArchived] = useState(false);\n const [deleteThreadId, setDeleteThreadId] = useState<string | null>(null);\n\n // Filter threads based on search and archive filter\n const filteredThreads = threads.filter(thread => {\n const title = (thread.title ?? '').toString();\n const matchesSearch = title.toLowerCase().includes(searchQuery.toLowerCase());\n const matchesArchiveFilter = showArchived || !thread.isArchived;\n return matchesSearch && matchesArchiveFilter;\n });\n\n // Group threads by date\n const groupedThreads = filteredThreads.reduce((groups, thread) => {\n const date = new Date(thread.updatedAt);\n const today = new Date();\n const yesterday = new Date(today.getTime() - 24 * 60 * 60 * 1000);\n \n let groupKey: string;\n if (date.toDateString() === today.toDateString()) {\n groupKey = config?.labels?.today || 'Today';\n } else if (date.toDateString() === yesterday.toDateString()) {\n groupKey = config?.labels?.yesterday || 'Yesterday';\n } else {\n groupKey = date.toLocaleDateString('en-US', {\n weekday: 'long',\n day: '2-digit',\n month: 'long',\n });\n }\n\n if (!groups[groupKey]) {\n groups[groupKey] = [];\n }\n groups[groupKey].push(thread);\n return groups;\n }, {} as Record<string, ChatThread[]>);\n\n const handleDeleteThread = (threadId: string) => {\n onDeleteThread?.(threadId);\n setDeleteThreadId(null);\n };\n\n if (!isOpen) return null;\n\n return (\n <TooltipProvider>\n <div className={`fixed inset-0 z-50 bg-background/80 backdrop-blur-sm ${className}`}>\n <div className=\"fixed left-0 top-0 h-full w-full max-w-md border-r bg-background shadow-lg\">\n <Card className=\"h-full border-0 rounded-none\">\n <CardHeader className=\"border-b\">\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"flex items-center gap-2\">\n <MessageSquare className=\"h-5 w-5\" />\n {config?.labels?.newChat || 'Conversations'}\n </CardTitle>\n <Button variant=\"ghost\" size=\"icon\" onClick={onClose} >\n <X className=\"h-4 w-4\" />\n </Button>\n </div>\n \n {/* Search and filters */}\n <div className=\"space-y-3\">\n <div className=\"relative\">\n <Search className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground\" />\n <Input\n placeholder={config?.labels?.search || \"Search conversations...\"}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"pl-9\"\n />\n </div>\n \n <div className=\"flex items-center justify-between\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setShowArchived(!showArchived)}\n className=\"text-xs\"\n >\n <Filter className=\"h-3 w-3 mr-1\" />\n {showArchived \n ? (config?.labels?.hideArchived || 'Hide Archived')\n : (config?.labels?.showArchived || 'Show Archived')}\n </Button>\n \n <Badge variant=\"secondary\" className=\"text-xs\">\n {filteredThreads.length} / {threads.length}\n </Badge>\n </div>\n </div>\n </CardHeader>\n\n <CardContent className=\"p-0 flex-1\">\n <div className=\"p-4\">\n {onCreateThread && (\n <CreateThreadDialog onCreateThread={onCreateThread} config={config} />\n )}\n </div>\n\n <ScrollArea className=\"h-[calc(100vh-280px)]\">\n <div className=\"px-4 pb-4 space-y-4\">\n {Object.keys(groupedThreads).length === 0 ? (\n <div className=\"text-center py-8 text-muted-foreground\">\n <MessageSquare className=\"h-12 w-12 mx-auto mb-3 opacity-50\" />\n <p className=\"text-sm\">\n {searchQuery \n ? (config?.labels?.noThreadsFound || 'No conversations found')\n : (config?.labels?.noThreadsYet || 'No conversations yet')}\n </p>\n </div>\n ) : (\n Object.entries(groupedThreads).map(([group, groupThreads]: [string, ChatThread[]]) => (\n <div key={group}>\n <h3 className=\"text-sm font-medium text-muted-foreground mb-2 px-2\">\n {group}\n </h3>\n <div className=\"space-y-2\">\n {groupThreads.map((thread) => (\n <ThreadItem\n key={thread.id}\n thread={thread}\n isActive={currentThreadId === thread.id}\n config={config}\n onSelect={() => onSelectThread?.(thread.id)}\n onRename={(newTitle) => onRenameThread?.(thread.id, newTitle)}\n onDelete={() => setDeleteThreadId(thread.id)}\n onArchive={() => onArchiveThread?.(thread.id)}\n />\n ))}\n </div>\n </div>\n ))\n )}\n </div>\n </ScrollArea>\n </CardContent>\n </Card>\n </div>\n\n {/* Delete confirmation dialog - only render when needed to avoid Radix focus conflicts */}\n {deleteThreadId && (\n <AlertDialog open={!!deleteThreadId} onOpenChange={() => setDeleteThreadId(null)}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>{config?.labels?.deleteConfirmTitle || 'Delete Conversation'}</AlertDialogTitle>\n <AlertDialogDescription>\n {config?.labels?.deleteConfirmDescription || 'Are you sure you want to delete this conversation? This action cannot be undone.'}\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>{config?.labels?.cancel || 'Cancel'}</AlertDialogCancel>\n <AlertDialogAction\n onClick={() => deleteThreadId && handleDeleteThread(deleteThreadId)}\n className=\"bg-destructive text-destructive-foreground hover:bg-destructive/90\"\n >\n {config?.labels?.deleteThread || 'Delete'}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n )}\n </div>\n </TooltipProvider>\n );\n};\n"],"mappings":"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","names":["Sidebar","import_react","import_jsx_runtime","import_react_slot","import_class_variance_authority","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","ThinkingIndicator","ThinkingBlock","remarkGfm","rehypeHighlight","LongContentShell","PlainTextContent","React","StreamingText","ReactMarkdown","MediaRenderer","formatDuration","ToolCallsDisplay","import_react","import_jsx_runtime","React","import_react_slot","import_class_variance_authority","import_lucide_react","React","import_jsx_runtime","React","import_lucide_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","open","React","import_lucide_react","import_jsx_runtime","cleanupBodyStyles","React","import_jsx_runtime","cleanupBodyStyles","import_lucide_react","import_jsx_runtime","import_lucide_react","import_lucide_react","import_jsx_runtime","import_jsx_runtime","Sidebar","import_react","import_lucide_react","import_react","import_lucide_react","import_jsx_runtime","import_jsx_runtime","React","import_react","import_react","import_jsx_runtime","offset","import_jsx_runtime","import_lucide_react","import_jsx_runtime","import_lucide_react","import_jsx_runtime","FileUploadItem","AttachmentPreview","formatDuration","AudioRecorder","ChatInput","React","import_react","React","import_jsx_runtime","import_lucide_react","import_jsx_runtime","getInitials","import_lucide_react","import_jsx_runtime","Sidebar","import_react","import_lucide_react","import_jsx_runtime","CreateThreadDialog"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/components/chat/ChatUI.tsx","../src/config/chatConfig.ts","../src/components/chat/Message.tsx","../src/lib/chatUtils.ts","../src/components/ui/button.tsx","../src/lib/utils.ts","../src/components/ui/avatar.tsx","../src/components/ui/badge.tsx","../src/components/ui/card.tsx","../src/components/ui/textarea.tsx","../src/components/ui/tooltip.tsx","../src/components/chat/Sidebar.tsx","../src/components/ui/input.tsx","../src/components/ui/sidebar.tsx","../src/hooks/use-mobile.ts","../src/components/ui/separator.tsx","../src/components/ui/sheet.tsx","../src/components/ui/skeleton.tsx","../src/components/ui/dialog.tsx","../src/components/ui/alert-dialog.tsx","../src/components/ui/dropdown-menu.tsx","../src/components/chat/UserMenu.tsx","../src/components/chat/ChatHeader.tsx","../src/components/chat/AgentSelectors.tsx","../src/components/chat/ChatInput.tsx","../src/components/chat/UserContext.tsx","../src/lib/voiceCompose.ts","../src/components/ui/progress.tsx","../src/components/chat/VoiceComposer.tsx","../src/components/chat/UserProfile.tsx","../src/components/ui/scroll-area.tsx","../src/components/chat/ThreadManager.tsx"],"sourcesContent":["export * from './components/chat/ChatUI';\nexport * from './components/chat/ChatHeader';\nexport * from './components/chat/AgentSelectors';\nexport * from './components/chat/ChatInput';\nexport * from './components/chat/Message';\nexport * from './components/chat/Sidebar';\nexport * from './components/chat/ThreadManager';\nexport * from './components/chat/UserContext';\nexport * from './components/chat/UserMenu';\nexport * from './components/chat/UserProfile';\nexport * from './config/chatConfig';\nexport * from './types/chatTypes';\nexport * from './lib/utils';\nexport * from './lib/chatUtils';\n","import React, { useState, useEffect, useRef, useCallback, useMemo } from 'react';\nimport { useVirtualizer } from '@tanstack/react-virtual';\nimport {\n ChatV2Props,\n ChatMessage,\n MediaAttachment,\n MessageActionEvent,\n StateCallback,\n ChatState,\n ChatUserContext,\n} from '../../types/chatTypes';\nimport { defaultChatConfig, mergeConfig } from '../../config/chatConfig';\nimport { Message } from './Message';\nimport { Sidebar } from './Sidebar';\nimport { ChatHeader } from './ChatHeader';\nimport { ChatInput } from './ChatInput';\nimport { TargetAgentSelector } from './AgentSelectors';\nimport { UserProfile } from './UserProfile';\nimport { useChatUserContext } from './UserContext';\nimport { ScrollArea } from '../ui/scroll-area';\nimport { Skeleton } from '../ui/skeleton';\nimport { TooltipProvider } from '../ui/tooltip';\nimport { SidebarProvider, SidebarInset } from '../ui/sidebar';\nimport { Sparkles, ArrowRight, MessageSquare, Lightbulb, Zap, HelpCircle } from 'lucide-react';\n\nfunction getMessageSpeakerKey(message: ChatMessage | null | undefined): string | null {\n if (!message) return null;\n if (message.role === 'assistant') {\n return message.senderAgentId ?? message.senderName ?? 'assistant';\n }\n if (message.role === 'user') {\n return 'user';\n }\n return message.role;\n}\n\n// ChatUI is a purely presentational component\nexport const ChatUI: React.FC<ChatV2Props> = ({\n messages = [],\n threads = [],\n currentThreadId = null,\n config: userConfig,\n sidebar: _sidebar,\n isGenerating = false,\n isMessagesLoading = false,\n callbacks = {},\n user,\n assistant,\n suggestions = [],\n messageSuggestions = {},\n agentOptions = [],\n selectedAgentId = null,\n onSelectAgent,\n participantIds,\n onParticipantsChange,\n targetAgentId = null,\n onTargetAgentChange,\n className = '',\n onAddMemory,\n onUpdateMemory,\n onDeleteMemory,\n initialInput,\n onInitialInputConsumed,\n}) => {\n // Merge configuration with defaults\n const config = useMemo(\n () => mergeConfig(defaultChatConfig, userConfig),\n [userConfig]\n );\n\n // Mobile detection\n const [isMobile, setIsMobile] = useState(false);\n\n // Built-in user profile panel state\n const [isUserProfileOpen, setIsUserProfileOpen] = useState(false);\n\n // Try to get user context for custom fields (may not be available if used outside provider)\n let userContext: ChatUserContext | undefined;\n try {\n const contextValue = useChatUserContext();\n userContext = contextValue?.context;\n } catch {\n // ChatUI used outside of ChatUserContextProvider, that's okay\n userContext = undefined;\n }\n\n // Check if desktop on initial render\n const getInitialSidebarState = () => {\n if (typeof globalThis.innerWidth === 'number') {\n return globalThis.innerWidth >= 1024; // Open on desktop (lg+)\n }\n return false;\n };\n\n // Separate input state to avoid full re-renders on every keystroke\n const [inputValue, setInputValue] = useState('');\n const [attachments, setAttachments] = useState<MediaAttachment[]>([]);\n const [expandedMessageIds, setExpandedMessageIds] = useState<Record<string, boolean>>({});\n\n // Internal state for UI only (excluding input to optimize re-renders)\n const [state, setState] = useState<Omit<ChatState, 'input' | 'attachments'>>({\n isRecording: false,\n selectedThreadId: currentThreadId,\n isAtBottom: true,\n showSidebar: getInitialSidebarState(), // Open by default on desktop\n showThreads: false, // No longer used for main sidebar\n editingMessageId: null,\n isSidebarCollapsed: false, // No longer used for main sidebar\n });\n\n // Update internal selected thread if prop changes\n useEffect(() => {\n if (currentThreadId !== state.selectedThreadId) {\n setState(prev => ({ ...prev, selectedThreadId: currentThreadId }));\n }\n }, [currentThreadId]);\n\n // Track if initialInput has been applied\n const initialInputApplied = useRef(false);\n const initialInputConsumedRef = useRef(false);\n\n // Apply initialInput when provided\n useEffect(() => {\n if (initialInput && !initialInputApplied.current) {\n setInputValue(initialInput);\n initialInputApplied.current = true;\n }\n }, [initialInput]);\n\n // Refs\n const scrollAreaRef = useRef<HTMLDivElement>(null);\n\n // Refs for state to avoid recreating callbacks on every state change\n const stateRef = useRef(state);\n const inputValueRef = useRef(inputValue);\n const attachmentsRef = useRef(attachments);\n\n // Keep refs in sync with state\n useEffect(() => { stateRef.current = state; }, [state]);\n useEffect(() => { inputValueRef.current = inputValue; }, [inputValue]);\n useEffect(() => { attachmentsRef.current = attachments; }, [attachments]);\n\n // Mobile custom overlay mount/unmount for smooth transitions\n const [isCustomMounted, setIsCustomMounted] = useState(false);\n const [isCustomVisible, setIsCustomVisible] = useState(false);\n\n // Virtualizer — only renders messages visible in the viewport + overscan buffer\n const virtualizer = useVirtualizer({\n count: messages.length,\n getScrollElement: () => scrollAreaRef.current,\n estimateSize: () => 100,\n overscan: 5,\n });\n\n // Create state callback helpers - uses refs to avoid recreating on every state change\n const createStateCallback = useCallback(\n (setter?: (value: React.SetStateAction<ChatState>) => void): StateCallback<ChatState> => ({\n setState: (newState) => setter?.(newState),\n getState: () => ({\n ...stateRef.current,\n input: inputValueRef.current,\n attachments: attachmentsRef.current,\n }),\n }),\n [] // No dependencies - uses refs for latest state\n );\n\n // Mobile detection effect\n useEffect(() => {\n const checkMobile = () => {\n setIsMobile(globalThis.innerWidth < 1024); // lg breakpoint\n };\n\n checkMobile();\n globalThis.addEventListener('resize', checkMobile);\n return () => globalThis.removeEventListener('resize', checkMobile);\n }, []);\n\n // Animate mobile custom component overlay\n useEffect(() => {\n if (!isMobile || !config.customComponent?.component) return;\n if (state.showSidebar) {\n setIsCustomMounted(true);\n requestAnimationFrame(() => setIsCustomVisible(true));\n } else {\n setIsCustomVisible(false);\n const t = setTimeout(() => setIsCustomMounted(false), 200);\n return () => clearTimeout(t);\n }\n }, [state.showSidebar, isMobile, config.customComponent]);\n\n // Track previous message count to detect initial load vs incremental updates\n const prevMessageCountRef = useRef(0);\n\n // Auto-scroll to bottom on message changes\n useEffect(() => {\n if (messages.length === 0) {\n prevMessageCountRef.current = 0;\n return;\n }\n\n const wasEmpty = prevMessageCountRef.current === 0;\n prevMessageCountRef.current = messages.length;\n\n if (wasEmpty) {\n // Initial load (thread switch) — jump instantly to the bottom\n // Double RAF ensures the virtualizer has committed its layout\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n virtualizer.scrollToIndex(messages.length - 1, { align: 'end' });\n });\n });\n return;\n }\n\n // Incremental update (new message, streaming) — smooth-scroll if at bottom\n if (!state.isAtBottom) return;\n requestAnimationFrame(() => {\n const viewport = scrollAreaRef.current;\n if (!viewport) return;\n try {\n viewport.scrollTo({ top: viewport.scrollHeight, behavior: 'smooth' });\n } catch {\n viewport.scrollTop = viewport.scrollHeight;\n }\n });\n }, [messages, state.isAtBottom, virtualizer]);\n\n useEffect(() => {\n virtualizer.measure();\n }, [expandedMessageIds, virtualizer]);\n\n useEffect(() => {\n const validMessageIds = new Set(messages.map((message) => message.id));\n\n setExpandedMessageIds((prev) => {\n const activeIds = Object.keys(prev);\n const staleIds = activeIds.filter((messageId) => !validMessageIds.has(messageId));\n\n if (staleIds.length === 0) {\n return prev;\n }\n\n const next = { ...prev };\n staleIds.forEach((messageId) => {\n delete next[messageId];\n });\n return next;\n });\n }, [messages]);\n\n // Handle scroll position — only update state when the value actually changes\n const handleScroll = useCallback((e: React.UIEvent<HTMLDivElement>) => {\n const { scrollTop, scrollHeight, clientHeight } = e.currentTarget;\n const isAtBottom = scrollHeight - scrollTop - clientHeight < 50;\n setState(prev => {\n if (prev.isAtBottom === isAtBottom) return prev;\n return { ...prev, isAtBottom };\n });\n }, []);\n\n // Message handling\n const handleSendMessage = useCallback((\n content: string,\n messageAttachments: MediaAttachment[] = []\n ) => {\n if (!content.trim() && messageAttachments.length === 0) return;\n \n // Call external callback\n callbacks.onSendMessage?.(content, messageAttachments, createStateCallback());\n\n // Mark initial input as consumed when message is sent\n if (initialInputApplied.current && !initialInputConsumedRef.current) {\n initialInputConsumedRef.current = true;\n onInitialInputConsumed?.();\n }\n\n // Clear input (using separate state for performance)\n setInputValue('');\n setAttachments([]);\n }, [callbacks, createStateCallback, onInitialInputConsumed]);\n\n // Message actions\n const handleMessageAction = useCallback((event: MessageActionEvent) => {\n const { action, messageId, content } = event;\n\n switch (action) {\n case 'copy':\n callbacks.onCopyMessage?.(messageId, content || '', createStateCallback());\n break;\n case 'edit':\n if (content) {\n callbacks.onEditMessage?.(messageId, content, createStateCallback());\n }\n break;\n case 'regenerate':\n callbacks.onRegenerateMessage?.(messageId, createStateCallback());\n break;\n case 'delete':\n callbacks.onDeleteMessage?.(messageId, createStateCallback());\n break;\n }\n }, [callbacks, createStateCallback]);\n\n const handleToggleMessageExpansion = useCallback((messageId: string) => {\n setExpandedMessageIds((prev) => {\n if (prev[messageId]) {\n const next = { ...prev };\n delete next[messageId];\n return next;\n }\n\n return {\n ...prev,\n [messageId]: true,\n };\n });\n }, []);\n\n // Thread management\n const handleCreateThread = useCallback((title?: string) => {\n callbacks.onCreateThread?.(title, createStateCallback());\n }, [callbacks, createStateCallback]);\n\n const handleSelectThread = useCallback((threadId: string) => {\n callbacks.onSelectThread?.(threadId, createStateCallback());\n }, [callbacks, createStateCallback]);\n\n const handleRenameThread = useCallback((threadId: string, newTitle: string) => {\n callbacks.onRenameThread?.(threadId, newTitle, createStateCallback());\n }, [callbacks, createStateCallback]);\n\n const handleDeleteThread = useCallback((threadId: string) => {\n callbacks.onDeleteThread?.(threadId, createStateCallback());\n }, [callbacks, createStateCallback]);\n\n const handleArchiveThread = useCallback((threadId: string) => {\n callbacks.onArchiveThread?.(threadId, createStateCallback());\n }, [callbacks, createStateCallback]);\n\n // Close sidebar handler\n const closeSidebar = useCallback(() => {\n setState(prev => ({ ...prev, showSidebar: false }));\n }, []);\n\n const handleCustomComponentToggle = useCallback(() => {\n setState(prev => ({ ...prev, showSidebar: !prev.showSidebar }));\n }, []);\n\n const sidebarUser = useMemo(() => user ? {\n id: user.id,\n name: user.name,\n email: user.email,\n avatar: user.avatar,\n } : null, [user?.id, user?.name, user?.email, user?.avatar]);\n\n const handleViewProfile = useCallback(() => {\n setIsUserProfileOpen(true);\n callbacks.onViewProfile?.();\n }, [callbacks.onViewProfile]);\n\n const sidebarUserMenuCallbacks = useMemo(() => ({\n onViewProfile: handleViewProfile,\n onOpenSettings: callbacks.onOpenSettings,\n onThemeChange: callbacks.onThemeChange,\n onLogout: callbacks.onLogout,\n }), [handleViewProfile, callbacks.onOpenSettings, callbacks.onThemeChange, callbacks.onLogout]);\n\n // Render custom component with props if it's a function\n const renderCustomComponent = useCallback(() => {\n const component = config?.customComponent?.component;\n if (!component) return null;\n if (typeof component === 'function') {\n return component({ onClose: closeSidebar, isMobile });\n }\n return component;\n }, [config?.customComponent?.component, closeSidebar, isMobile]);\n\n // Icon components for suggestion cards (cycle through these)\n const SuggestionIconComponents = [MessageSquare, Lightbulb, Zap, HelpCircle];\n\n // Render suggestions\n const renderSuggestions = () => {\n if (messages.length > 0 || !suggestions.length) return null;\n\n return (\n <div className=\"flex flex-col items-center justify-center min-h-[60vh] py-8 px-4\">\n {/* Hero section */}\n <div className=\"text-center mb-8\">\n <div className=\"inline-flex items-center justify-center w-14 h-14 rounded-2xl bg-gradient-to-br from-primary/20 to-primary/5 mb-4 shadow-sm\">\n <Sparkles className=\"w-7 h-7 text-primary\" />\n </div>\n <h2 className=\"text-xl font-semibold mb-2\">{config.branding.title}</h2>\n <p className=\"text-muted-foreground text-sm max-w-md\">{config.branding.subtitle}</p>\n </div>\n\n {/* Suggestion cards */}\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-3 w-full max-w-2xl\">\n {suggestions.map((suggestion, index) => (\n <button\n key={index}\n type=\"button\"\n onClick={() => handleSendMessage(suggestion)}\n className=\"group relative flex items-start gap-3 p-4 text-left rounded-xl border bg-card hover:bg-accent/50 hover:border-accent transition-all duration-200 hover:shadow-sm\"\n >\n {(() => {\n const IconComponent = SuggestionIconComponents[index % SuggestionIconComponents.length];\n return (\n <div className=\"flex items-center justify-center w-8 h-8 rounded-lg bg-primary/10 text-primary shrink-0 group-hover:bg-primary/15 transition-colors\">\n <IconComponent className=\"h-4 w-4\" />\n </div>\n );\n })()}\n <div className=\"flex-1 min-w-0 pr-6\">\n <p className=\"text-sm font-medium leading-snug line-clamp-2\">{suggestion}</p>\n </div>\n <ArrowRight className=\"absolute right-4 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground opacity-0 group-hover:opacity-100 transition-opacity\" />\n </button>\n ))}\n </div>\n </div>\n );\n };\n\n const renderInlineSuggestions = (messageId: string) => {\n const items = messageSuggestions?.[messageId];\n if (!items || items.length === 0) return null;\n const inlineSuggestionOffsetClass = config.ui.showAvatars\n ? (config.ui.compactMode ? 'ml-9' : 'ml-11')\n : '';\n\n return (\n <div className={`flex flex-wrap gap-2 mt-2 ${inlineSuggestionOffsetClass}`}>\n {items.map((suggestion, index) => (\n <button\n key={`${messageId}-suggestion-${index}`}\n type=\"button\"\n onClick={() => handleSendMessage(suggestion)}\n className=\"group inline-flex items-center gap-1.5 px-3 py-1.5 text-sm rounded-full border border-border bg-background hover:bg-accent hover:border-accent-foreground/20 transition-all duration-150 text-foreground/80 hover:text-foreground\"\n >\n <Sparkles className=\"h-3 w-3 text-primary opacity-70 group-hover:opacity-100\" />\n <span className=\"max-w-[200px] truncate\">{suggestion}</span>\n </button>\n ))}\n </div>\n );\n };\n\n const renderMessageLoadingSkeleton = () => (\n <div className=\"space-y-6 py-2\">\n {[0, 1, 2, 3].map((index) => {\n const isUserRow = index % 2 === 1;\n return (\n <div\n key={`message-skeleton-${index}`}\n className={`flex gap-3 ${isUserRow ? 'justify-end' : 'justify-start'}`}\n >\n {!isUserRow && <Skeleton className=\"h-8 w-8 rounded-full shrink-0\" />}\n <div className={`space-y-2 ${isUserRow ? 'w-[70%]' : 'w-[75%]'}`}>\n <Skeleton className=\"h-4 w-24\" />\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-4 w-[85%]\" />\n </div>\n {isUserRow && <Skeleton className=\"h-8 w-8 rounded-full shrink-0\" />}\n </div>\n );\n })}\n </div>\n );\n\n const isMultiAgentMode = config.agentSelector?.mode === 'multi';\n\n // Stable props object for Message components — prevents unnecessary re-renders\n // when the virtualizer re-evaluates which items to show\n const messageProps = useMemo(() => ({\n userAvatar: user?.avatar,\n userName: user?.name,\n assistantAvatar: assistant?.avatar,\n assistantName: assistant?.name,\n showTimestamp: config.ui.showTimestamps,\n showAvatar: config.ui.showAvatars,\n enableCopy: config.features.enableMessageCopy,\n enableEdit: config.features.enableMessageEditing,\n enableRegenerate: config.features.enableRegeneration,\n enableToolCallsDisplay: config.features.enableToolCallsDisplay,\n compactMode: config.ui.compactMode,\n onAction: handleMessageAction,\n toolUsedLabel: config.labels.toolUsed,\n thinkingLabel: config.labels.thinking,\n showMoreLabel: config.labels.showMoreMessage,\n showLessLabel: config.labels.showLessMessage,\n collapseLongMessages: config.ui.collapseLongMessages,\n collapseLongMessagesForUserOnly: config.ui.collapseLongMessagesForUserOnly,\n longMessagePreviewChars: config.ui.longMessagePreviewChars,\n longMessageChunkChars: config.ui.longMessageChunkChars,\n renderUserMarkdown: config.ui.renderUserMarkdown,\n markdown: config.markdown,\n onToggleExpanded: handleToggleMessageExpansion,\n agentOptions: isMultiAgentMode ? agentOptions : undefined,\n }), [\n user?.avatar,\n user?.name,\n assistant?.avatar,\n assistant?.name,\n isMultiAgentMode,\n agentOptions,\n config.ui.showTimestamps,\n config.ui.showAvatars,\n config.ui.compactMode,\n config.features.enableMessageCopy,\n config.features.enableMessageEditing,\n config.features.enableRegeneration,\n config.features.enableToolCallsDisplay,\n config.labels.toolUsed,\n config.labels.thinking,\n config.labels.showMoreMessage,\n config.labels.showLessMessage,\n config.ui.collapseLongMessages,\n config.ui.collapseLongMessagesForUserOnly,\n config.ui.longMessagePreviewChars,\n config.ui.longMessageChunkChars,\n config.ui.renderUserMarkdown,\n config.markdown,\n handleMessageAction,\n handleToggleMessageExpansion,\n ]);\n\n const shouldShowAgentSelector = Boolean(\n config.agentSelector?.enabled &&\n agentOptions.length > 0 &&\n (!config.agentSelector?.hideIfSingle || agentOptions.length > 1) &&\n (isMultiAgentMode ? onParticipantsChange : onSelectAgent)\n );\n\n return (\n <TooltipProvider>\n <SidebarProvider defaultOpen>\n <div className={`flex h-[100svh] md:h-screen bg-background w-full overflow-hidden ${className}`}>\n \n <Sidebar\n threads={threads}\n currentThreadId={state.selectedThreadId}\n config={config}\n onCreateThread={handleCreateThread}\n onSelectThread={handleSelectThread}\n onRenameThread={handleRenameThread}\n onDeleteThread={handleDeleteThread}\n onArchiveThread={handleArchiveThread}\n // User menu props\n user={sidebarUser}\n userMenuCallbacks={sidebarUserMenuCallbacks}\n currentTheme={config.ui.theme === 'auto' ? 'system' : config.ui.theme}\n showThemeOptions={!!callbacks.onThemeChange}\n />\n\n <SidebarInset>\n <div className=\"flex flex-col h-full min-h-0\">\n {/* Header */}\n <ChatHeader\n config={config}\n currentThreadTitle={threads.find(t => t.id === state.selectedThreadId)?.title}\n // onSidebarToggle is now handled by SidebarTrigger inside ChatHeader\n isMobile={isMobile}\n onCustomComponentToggle={handleCustomComponentToggle}\n onNewThread={handleCreateThread}\n showCustomComponentButton={!!config?.customComponent?.component}\n showAgentSelector={shouldShowAgentSelector}\n isMultiAgentMode={isMultiAgentMode}\n agentOptions={agentOptions}\n selectedAgentId={selectedAgentId}\n onSelectAgent={onSelectAgent}\n participantIds={participantIds}\n onParticipantsChange={onParticipantsChange}\n />\n\n <div className=\"flex flex-1 flex-row min-h-0 overflow-hidden\">\n {/* Main Chat Area */}\n <div className=\"flex-1 flex flex-col min-h-0\">\n {/* Messages — contain: strict prevents reflow from propagating to/from the input */}\n <ScrollArea\n ref={scrollAreaRef}\n className=\"flex-1 min-h-0\"\n viewportClassName=\"p-4 overscroll-contain\"\n onScrollCapture={handleScroll}\n style={{ contain: 'strict' }}\n >\n <div className=\"max-w-4xl mx-auto pb-4\">\n {isMessagesLoading ? (\n renderMessageLoadingSkeleton()\n ) : messages.length === 0 ? (\n renderSuggestions()\n ) : (\n <div\n style={{\n height: `${virtualizer.getTotalSize()}px`,\n width: '100%',\n position: 'relative',\n }}\n >\n {virtualizer.getVirtualItems().map((virtualRow) => {\n const message = messages[virtualRow.index];\n const prevMessage = virtualRow.index > 0 ? messages[virtualRow.index - 1] : null;\n const isGrouped = prevMessage !== null &&\n prevMessage.role === message.role &&\n getMessageSpeakerKey(prevMessage) === getMessageSpeakerKey(message);\n\n return (\n <div\n key={message.id}\n data-index={virtualRow.index}\n ref={virtualizer.measureElement}\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n width: '100%',\n transform: `translateY(${virtualRow.start}px)`,\n }}\n >\n <div className={virtualRow.index === 0 ? '' : isGrouped ? 'pt-2' : 'pt-4'}>\n <Message\n message={message}\n {...messageProps}\n isGrouped={isGrouped}\n isExpanded={Boolean(expandedMessageIds[message.id])}\n />\n {message.role === 'assistant' && renderInlineSuggestions(message.id)}\n </div>\n </div>\n );\n })}\n </div>\n )}\n </div>\n </ScrollArea>\n\n {/* Input */}\n <div className=\"bg-background pb-[env(safe-area-inset-bottom)]\">\n {/* Target agent selector for multi-agent mode */}\n {isMultiAgentMode && shouldShowAgentSelector && onTargetAgentChange && (\n <div className=\"px-4 pt-1\">\n <TargetAgentSelector\n agents={participantIds && participantIds.length > 0\n ? agentOptions.filter(a => participantIds.includes(a.id))\n : agentOptions}\n targetAgentId={targetAgentId}\n onTargetChange={onTargetAgentChange}\n placeholder={config.agentSelector?.label || 'Select agent'}\n disabled={isGenerating}\n />\n </div>\n )}\n <ChatInput\n value={inputValue}\n onChange={(value) => {\n setInputValue(value);\n // Mark initial input as consumed when user modifies it\n if (initialInputApplied.current && !initialInputConsumedRef.current) {\n initialInputConsumedRef.current = true;\n onInitialInputConsumed?.();\n }\n }}\n onSubmit={handleSendMessage}\n attachments={attachments}\n onAttachmentsChange={setAttachments}\n placeholder={config.labels.inputPlaceholder}\n disabled={false}\n isGenerating={isGenerating}\n onStopGeneration={callbacks.onStopGeneration}\n enableFileUpload={config.features.enableFileUpload}\n enableAudioRecording={config.features.enableAudioRecording}\n maxAttachments={config.features.maxAttachments}\n maxFileSize={config.features.maxFileSize}\n config={config}\n mentionAgents={participantIds && participantIds.length > 0\n ? agentOptions.filter(a => participantIds.includes(a.id))\n : agentOptions}\n onTargetAgentChange={onTargetAgentChange}\n />\n </div>\n </div>\n\n {/* Right sidebar custom component for desktop */}\n {config?.customComponent?.component && !isMobile && (\n <div\n className=\"h-full transition-all duration-300 ease-in-out overflow-hidden\"\n style={{ width: state.showSidebar ? (config.customComponent.panelWidth ?? 320) : 0 }}\n >\n {state.showSidebar && (\n <div\n className=\"h-full overflow-hidden border-l bg-background animate-in slide-in-from-right-4 duration-300\"\n style={{ width: config.customComponent.panelWidth ?? 320 }}\n >\n {renderCustomComponent()}\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n </SidebarInset>\n\n {/* Mobile custom sidebar overlay with smooth transitions (slides from right) */}\n {isCustomMounted && config.customComponent?.component && isMobile && (\n <div className=\"fixed inset-0 z-50\">\n {/* Backdrop */}\n <div\n className={`absolute inset-0 bg-background/80 backdrop-blur-sm transition-opacity duration-200 ease-out ${\n isCustomVisible ? 'opacity-100' : 'opacity-0'\n }`}\n style={{ willChange: 'opacity' }}\n onClick={closeSidebar}\n />\n {/* Panel - slides from right */}\n <div\n className={`absolute top-0 right-0 h-full w-full bg-background transform-gpu transition-transform duration-200 ease-out ${\n isCustomVisible ? 'translate-x-0' : 'translate-x-full'\n }`}\n style={{ willChange: 'transform' }}\n >\n <div className=\"h-full overflow-hidden\">\n {renderCustomComponent()}\n </div>\n </div>\n </div>\n )}\n\n {/* Built-in User Profile Panel - only render when open to avoid Radix focus conflicts */}\n {isUserProfileOpen && (\n <UserProfile\n isOpen={isUserProfileOpen}\n onClose={() => setIsUserProfileOpen(false)}\n user={user ? {\n id: user.id,\n name: user.name,\n email: user.email,\n avatar: user.avatar,\n } : null}\n customFields={userContext?.customFields}\n memories={userContext?.memories?.items}\n onLogout={callbacks.onLogout}\n onAddMemory={onAddMemory}\n onUpdateMemory={onUpdateMemory}\n onDeleteMemory={onDeleteMemory}\n />\n )}\n </div>\n </SidebarProvider>\n </TooltipProvider>\n );\n};\n","import { ChatConfig } from '../types/chatTypes';\n\n// Default configuration\nexport const defaultChatConfig: Required<ChatConfig> = {\n\n branding: {\n logo: null,\n avatar: null,\n title: 'Chat Assistant',\n subtitle: 'How can I help you today?',\n },\n\n agentSelector: {\n enabled: false,\n label: 'Select agent',\n hideIfSingle: true,\n },\n \n labels: {\n inputPlaceholder: 'Type your message...',\n sendButton: 'Send',\n sendMessageTooltip: 'Send message',\n newThread: 'New Conversation',\n deleteThread: 'Delete Conversation',\n copyMessage: 'Copy',\n editMessage: 'Edit',\n regenerateMessage: 'Regenerate',\n stopGeneration: 'Stop',\n stopGenerationTooltip: 'Stop generation',\n attachFiles: 'Attach Files',\n attachFileTooltip: 'Attach file',\n recordAudio: 'Record Audio',\n recordAudioTooltip: 'Record audio',\n voiceEnter: 'Voice input',\n voiceExit: 'Use keyboard',\n voiceTitle: 'Voice',\n voiceIdle: 'Tap the mic to record',\n voicePreparing: 'Preparing microphone...',\n voiceWaiting: 'Waiting for speech...',\n voiceListening: 'Listening...',\n voiceFinishing: 'Finishing capture...',\n voiceReview: 'Ready to send',\n voiceSending: 'Sending...',\n voiceReviewArmedHint: 'Still listening. Speak to add more before it sends.',\n voiceReviewPausedHint: 'Tap the mic to keep adding to this message.',\n voiceStart: 'Start recording',\n voiceStop: 'Stop recording',\n voiceSendNow: 'Send now',\n voiceCancel: 'Cancel',\n voiceDiscard: 'Delete recording',\n voiceRecordAgain: 'Continue recording',\n voiceAutoSendIn: 'Auto-sends in {{seconds}}s',\n voiceTranscriptPending: 'Transcript unavailable',\n voicePermissionDenied: 'Microphone access was denied.',\n voiceCaptureError: 'Unable to capture audio.',\n // Header labels\n exportData: 'Export data',\n importData: 'Import data',\n clearAll: 'Clear all',\n sidebarToggle: 'Menu',\n customComponentToggle: 'Toggle',\n settings: 'Settings',\n toggleDarkMode: 'Toggle Dark Mode',\n lightMode: 'Light Mode',\n darkMode: 'Dark Mode',\n // Sidebar labels\n newChat: 'New Conversation',\n search: 'Search conversations...',\n customComponentLabel: 'Custom',\n showArchived: 'Show Archived',\n hideArchived: 'Hide Archived',\n noThreadsFound: 'No conversations found',\n noThreadsYet: 'No conversations yet',\n deleteConfirmTitle: 'Delete Conversation',\n deleteConfirmDescription: 'Are you sure you want to delete this conversation? This action cannot be undone. All messages will be permanently lost.',\n renameThread: 'Rename',\n archiveThread: 'Archive',\n unarchiveThread: 'Unarchive',\n today: 'Today',\n yesterday: 'Yesterday',\n createNewThread: 'Create New Conversation',\n threadNamePlaceholder: 'Conversation name (optional)',\n cancel: 'Cancel',\n create: 'Create Conversation',\n footerLabel: 'Assistant can make mistakes. Check the AI results.',\n toolUsed: 'Tool Used',\n daysAgo: 'days ago',\n inputHelpText: 'Press Enter to send, Shift+Enter to add a new line.',\n thinking: 'Thinking...',\n defaultThreadName: 'Main Thread',\n showMoreMessage: 'Show more',\n showLessMessage: 'Show less',\n },\n \n features: {\n enableThreads: true,\n enableFileUpload: true,\n enableAudioRecording: true,\n enableMessageEditing: true,\n enableMessageCopy: true,\n enableRegeneration: true,\n enableToolCallsDisplay: true,\n maxAttachments: 4,\n maxFileSize: 10 * 1024 * 1024, // 10MB\n },\n \n ui: {\n theme: 'auto' as const,\n showTimestamps: false,\n showAvatars: true,\n compactMode: false,\n showWordCount: false,\n collapseLongMessages: false,\n collapseLongMessagesForUserOnly: false,\n longMessagePreviewChars: 4000,\n longMessageChunkChars: 12000,\n renderUserMarkdown: true,\n },\n\n markdown: {\n remarkPlugins: [],\n rehypePlugins: [],\n components: {},\n },\n\n voiceCompose: {\n enabled: false,\n defaultMode: 'text',\n reviewMode: 'manual',\n autoSendDelayMs: 5000,\n persistComposer: true,\n showTranscriptPreview: true,\n transcriptMode: 'final-only',\n maxRecordingMs: 60000,\n createProvider: undefined,\n },\n \n customComponent: {},\n headerActions: null,\n};\n\n// Deep merge function for configurations\nexport function mergeConfig(_baseConfig: ChatConfig, userConfig?: Partial<ChatConfig>): Required<ChatConfig> {\n if (!userConfig) return defaultChatConfig;\n\n return {\n branding: {\n ...defaultChatConfig.branding,\n ...userConfig.branding,\n },\n labels: {\n ...defaultChatConfig.labels,\n ...userConfig.labels,\n },\n features: {\n ...defaultChatConfig.features,\n ...userConfig.features,\n },\n ui: {\n ...defaultChatConfig.ui,\n ...userConfig.ui,\n },\n markdown: {\n ...defaultChatConfig.markdown,\n ...userConfig.markdown,\n },\n voiceCompose: {\n ...defaultChatConfig.voiceCompose,\n ...userConfig.voiceCompose,\n },\n agentSelector: {\n ...defaultChatConfig.agentSelector,\n ...userConfig.agentSelector,\n },\n customComponent: userConfig.customComponent || defaultChatConfig.customComponent,\n headerActions: userConfig.headerActions || defaultChatConfig.headerActions,\n };\n}\n\n","import React, { useState, useMemo, useEffect, memo } from 'react';\nimport ReactMarkdown, { type Components } from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport rehypeHighlight from 'rehype-highlight';\nimport { ChatMarkdownConfig, ChatMessage, AgentOption, MediaAttachment, ToolCall, MessageActionEvent } from '../../types/chatTypes';\nimport { getAgentColor, getAgentInitials } from '../../lib/chatUtils';\nimport { Button } from '../ui/button';\nimport { Avatar, AvatarFallback, AvatarImage } from '../ui/avatar';\nimport { Badge } from '../ui/badge';\nimport { Card, CardContent } from '../ui/card';\nimport { Textarea } from '../ui/textarea';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '../ui/tooltip';\nimport { createObjectUrlFromDataUrl } from '../../lib/utils';\nimport {\n Copy,\n Edit,\n RotateCcw,\n Check,\n X,\n Wrench,\n Clock,\n ChevronRight,\n ChevronDown,\n Brain\n} from 'lucide-react';\n\n\ninterface MessageProps {\n message: ChatMessage;\n isUser?: boolean;\n userAvatar?: string;\n userName?: string;\n assistantAvatar?: React.ReactNode;\n assistantName?: string;\n showTimestamp?: boolean;\n showAvatar?: boolean;\n enableCopy?: boolean;\n enableEdit?: boolean;\n enableRegenerate?: boolean;\n enableToolCallsDisplay?: boolean;\n compactMode?: boolean;\n onAction?: (event: MessageActionEvent) => void;\n className?: string;\n toolUsedLabel?: string;\n thinkingLabel?: string;\n showMoreLabel?: string;\n showLessLabel?: string;\n collapseLongMessages?: boolean;\n collapseLongMessagesForUserOnly?: boolean;\n longMessagePreviewChars?: number;\n longMessageChunkChars?: number;\n renderUserMarkdown?: boolean;\n markdown?: ChatMarkdownConfig;\n isExpanded?: boolean;\n onToggleExpanded?: (messageId: string) => void;\n /** When true, hides the avatar and name (for grouped consecutive messages from same sender) */\n isGrouped?: boolean;\n /** Available agents for resolving multi-agent display (colors, avatars) */\n agentOptions?: AgentOption[];\n}\n\n// Thinking indicator component - memoized since it's rendered during streaming\nconst ThinkingIndicator: React.FC<{ label?: string }> = memo(function ThinkingIndicator({ label = 'Thinking...' }: { label?: string }) {\n return (\n <div className=\"flex items-center gap-2 py-2\">\n <div className=\"flex gap-1\">\n <span \n className=\"inline-block w-2 h-2 bg-primary rounded-full animate-bounce\" \n style={{ animationDelay: '0ms' }} \n />\n <span \n className=\"inline-block w-2 h-2 bg-primary rounded-full animate-bounce\" \n style={{ animationDelay: '150ms' }} \n />\n <span \n className=\"inline-block w-2 h-2 bg-primary rounded-full animate-bounce\" \n style={{ animationDelay: '300ms' }} \n />\n </div>\n <span className=\"text-sm text-muted-foreground animate-pulse\">{label}</span>\n </div>\n );\n});\n\n// Claude-like collapsible reasoning/thinking block\nconst ThinkingBlock: React.FC<{\n reasoning: string;\n isStreaming?: boolean;\n label?: string;\n}> = memo(function ThinkingBlock({ reasoning, isStreaming = false, label = 'Thinking...' }) {\n const [isOpen, setIsOpen] = useState(isStreaming);\n\n useEffect(() => {\n if (isStreaming) setIsOpen(true);\n }, [isStreaming]);\n\n const finishedLabel = label.replace(/\\.{3}$/, '');\n\n return (\n <div className={`mb-3 rounded-lg border ${isStreaming ? 'border-primary/40 bg-primary/5' : 'border-border/60 bg-muted/30'} overflow-hidden transition-colors duration-300`}>\n <button\n type=\"button\"\n className=\"flex w-full items-center gap-2 px-3 py-2 text-left text-sm font-medium text-muted-foreground hover:text-foreground transition-colors\"\n onClick={() => setIsOpen(!isOpen)}\n >\n <Brain className={`h-4 w-4 flex-shrink-0 ${isStreaming ? 'text-primary animate-pulse' : 'text-muted-foreground'}`} />\n <span className=\"flex-1\">\n {isStreaming ? label : finishedLabel}\n </span>\n {isStreaming && (\n <div className=\"flex gap-0.5 mr-1\">\n <span className=\"inline-block w-1 h-1 bg-primary rounded-full animate-bounce\" style={{ animationDelay: '0ms' }} />\n <span className=\"inline-block w-1 h-1 bg-primary rounded-full animate-bounce\" style={{ animationDelay: '150ms' }} />\n <span className=\"inline-block w-1 h-1 bg-primary rounded-full animate-bounce\" style={{ animationDelay: '300ms' }} />\n </div>\n )}\n {isOpen ? <ChevronDown className=\"h-3 w-3 flex-shrink-0\" /> : <ChevronRight className=\"h-3 w-3 flex-shrink-0\" />}\n </button>\n {isOpen && (\n <div className=\"px-3 pb-3 text-sm text-muted-foreground leading-relaxed whitespace-pre-wrap break-words border-t border-border/40\">\n <div className=\"pt-2\">\n {reasoning}\n {isStreaming && <span className=\"inline-block w-1.5 h-3.5 bg-primary/60 animate-pulse ml-0.5\" />}\n </div>\n </div>\n )}\n </div>\n );\n});\n\n// Memoized markdown components configuration to prevent recreation on every render\nconst defaultMarkdownComponents: Components = {\n code: ({ node, className, children, ...props }: any) => {\n const inline = (props as { inline?: boolean }).inline;\n const match = /language-(\\w+)/.exec(className || '');\n return !inline && match ? (\n <pre className=\"relative\">\n <code className={className} {...props}>\n {children}\n </code>\n </pre>\n ) : (\n <code className=\"bg-muted px-1 py-0.5 rounded text-sm\" {...props}>\n {children}\n </code>\n );\n },\n};\n\n// Memoized plugins arrays to prevent recreation\nconst remarkPluginsDefault = [remarkGfm] as NonNullable<ChatMarkdownConfig['remarkPlugins']>;\nconst rehypePluginsDefault = [rehypeHighlight] as NonNullable<ChatMarkdownConfig['rehypePlugins']>;\nconst rehypePluginsEmpty = [] as NonNullable<ChatMarkdownConfig['rehypePlugins']>;\n\nconst getPlainTextChunks = (content: string, chunkSize: number): string[] => {\n if (chunkSize <= 0 || content.length <= chunkSize) {\n return [content];\n }\n\n const chunks: string[] = [];\n let start = 0;\n\n while (start < content.length) {\n let end = Math.min(start + chunkSize, content.length);\n\n if (end < content.length) {\n const splitAt = content.lastIndexOf('\\n', end);\n if (splitAt > start + Math.floor(chunkSize / 2)) {\n end = splitAt + 1;\n }\n }\n\n chunks.push(content.slice(start, end));\n start = end;\n }\n\n return chunks;\n};\n\nconst hasCodeBlocks = (content: string): boolean => /(^|\\n)(```|~~~)/.test(content);\n\nconst getCollapsedPreview = (content: string, previewChars: number, previewOverride?: string): string => {\n if (previewOverride && previewOverride.trim().length > 0) {\n const normalizedPreview = previewOverride.trimEnd();\n return normalizedPreview.endsWith('...') ? normalizedPreview : `${normalizedPreview}...`;\n }\n\n if (content.length <= previewChars) {\n return content;\n }\n\n return `${content.slice(0, previewChars).trimEnd()}...`;\n};\n\nconst LongContentShell: React.FC<{\n children: React.ReactNode;\n className: string;\n style?: React.CSSProperties;\n}> = memo(function LongContentShell({ children, className, style }) {\n return (\n <div className={className} style={style}>\n {children}\n </div>\n );\n});\n\nconst PlainTextContent: React.FC<{\n content: string;\n className?: string;\n chunkSize?: number;\n style?: React.CSSProperties;\n}> = memo(function PlainTextContent({\n content,\n className = '',\n chunkSize = 12000,\n style,\n}) {\n const chunks = useMemo(() => getPlainTextChunks(content, chunkSize), [content, chunkSize]);\n\n return (\n <LongContentShell\n className={`text-sm leading-6 whitespace-pre-wrap break-words ${className}`.trim()}\n style={style}\n >\n {chunks.map((chunk, index) => (\n <React.Fragment key={index}>{chunk}</React.Fragment>\n ))}\n </LongContentShell>\n );\n});\n\n// Streaming text component for real-time markdown rendering - memoized to prevent unnecessary re-renders\nconst StreamingText: React.FC<{\n content: string;\n isStreaming?: boolean;\n thinkingLabel?: string;\n className?: string;\n renderMarkdown?: boolean;\n markdown?: ChatMarkdownConfig;\n plainTextChunkChars?: number;\n contentStyle?: React.CSSProperties;\n hideThinkingIndicator?: boolean;\n}> = memo(function StreamingText({\n content,\n isStreaming = false,\n thinkingLabel = 'Thinking...',\n className = '',\n renderMarkdown = true,\n markdown,\n plainTextChunkChars = 12000,\n contentStyle,\n hideThinkingIndicator = false,\n}: {\n content: string;\n isStreaming?: boolean;\n thinkingLabel?: string;\n className?: string;\n renderMarkdown?: boolean;\n markdown?: ChatMarkdownConfig;\n plainTextChunkChars?: number;\n contentStyle?: React.CSSProperties;\n hideThinkingIndicator?: boolean;\n}) {\n const hasContent = content.trim().length > 0;\n const enableSyntaxHighlight = renderMarkdown && !isStreaming && hasCodeBlocks(content);\n const mergedComponents = useMemo<Components>(\n () => ({\n ...defaultMarkdownComponents,\n ...markdown?.components,\n }),\n [markdown?.components],\n );\n const mergedRemarkPlugins = useMemo<NonNullable<ChatMarkdownConfig['remarkPlugins']>>(\n () => [\n ...remarkPluginsDefault,\n ...(markdown?.remarkPlugins ?? []),\n ],\n [markdown?.remarkPlugins],\n );\n const mergedRehypePlugins = useMemo<NonNullable<ChatMarkdownConfig['rehypePlugins']>>(\n () => [\n ...(enableSyntaxHighlight ? rehypePluginsDefault : rehypePluginsEmpty),\n ...(markdown?.rehypePlugins ?? []),\n ],\n [enableSyntaxHighlight, markdown?.rehypePlugins],\n );\n\n return (\n <>\n {hasContent ? (\n renderMarkdown ? (\n <LongContentShell\n className={`prose prose-sm max-w-none dark:prose-invert break-words ${className}`.trim()}\n style={contentStyle}\n >\n <ReactMarkdown\n remarkPlugins={mergedRemarkPlugins}\n rehypePlugins={mergedRehypePlugins}\n components={mergedComponents}\n >\n {content}\n </ReactMarkdown>\n </LongContentShell>\n ) : (\n <PlainTextContent\n content={content}\n className={className}\n chunkSize={plainTextChunkChars}\n style={contentStyle}\n />\n )\n ) : isStreaming && !hideThinkingIndicator ? (\n <ThinkingIndicator label={thinkingLabel} />\n ) : null}\n {isStreaming && hasContent && (\n <span className=\"inline-block w-2 h-4 bg-primary animate-pulse ml-1\" />\n )}\n </>\n );\n});\n\n// Media attachment renderer - memoized to prevent unnecessary re-renders\nconst MediaRenderer: React.FC<{ attachment: MediaAttachment }> = memo(function MediaRenderer({ attachment }) {\n const [audioPlaybackSrc, setAudioPlaybackSrc] = useState(attachment.dataUrl);\n\n useEffect(() => {\n if (attachment.kind !== 'audio' || !attachment.dataUrl.startsWith('data:')) {\n setAudioPlaybackSrc(attachment.dataUrl);\n return;\n }\n\n const objectUrl = createObjectUrlFromDataUrl(attachment.dataUrl);\n if (!objectUrl) {\n setAudioPlaybackSrc(attachment.dataUrl);\n return;\n }\n\n setAudioPlaybackSrc(objectUrl);\n\n return () => {\n URL.revokeObjectURL(objectUrl);\n };\n }, [attachment.kind, attachment.dataUrl]);\n\n const formatDuration = (ms?: number) => {\n if (!ms) return '';\n const seconds = Math.floor(ms / 1000);\n const minutes = Math.floor(seconds / 60);\n return `${minutes}:${(seconds % 60).toString().padStart(2, '0')}`;\n };\n\n switch (attachment.kind) {\n case 'image':\n return (\n <div className=\"relative rounded-lg overflow-hidden border bg-muted/20 max-w-md\">\n <img\n src={attachment.dataUrl}\n alt={attachment.fileName || 'Attachment'}\n className=\"w-full h-auto object-cover\"\n loading=\"lazy\"\n />\n {attachment.fileName && (\n <div className=\"absolute bottom-0 left-0 right-0 bg-black/50 text-white text-xs p-2\">\n {attachment.fileName}\n </div>\n )}\n </div>\n );\n\n case 'audio':\n return (\n <div className=\"flex w-full max-w-md py-0 min-w-64 items-center gap-3\">\n <audio\n className=\"w-full mt-2\"\n preload=\"metadata\"\n controls\n >\n <source src={audioPlaybackSrc} type={attachment.mimeType} />\n </audio>\n </div>\n );\n\n case 'video':\n return (\n <div className=\"relative rounded-lg overflow-hidden border bg-muted/20 max-w-lg\">\n <video\n src={attachment.dataUrl}\n poster={attachment.poster}\n controls\n className=\"w-full h-auto\"\n />\n {attachment.fileName && (\n <div className=\"absolute bottom-0 left-0 right-0 bg-black/50 text-white text-xs p-2\">\n {attachment.fileName}\n </div>\n )}\n </div>\n );\n\n default:\n return null;\n }\n});\n\n// Tool calls display component - memoized to prevent unnecessary re-renders\nconst ToolCallsDisplay: React.FC<{ toolCalls: ToolCall[]; label?: string }> = memo(function ToolCallsDisplay({ toolCalls, label }) {\n const [expandedCall, setExpandedCall] = useState<string | null>(null);\n\n const getStatusIcon = (status: ToolCall['status']) => {\n switch (status) {\n case 'pending':\n return <Clock className=\"h-3 w-3 text-muted-foreground\" />;\n case 'running':\n return <div className=\"h-3 w-3 border-2 border-primary border-t-transparent rounded-full animate-spin\" />;\n case 'completed':\n return <Check className=\"h-3 w-3 text-green-500\" />;\n case 'failed':\n return <X className=\"h-3 w-3 text-destructive\" />;\n }\n };\n\n const getStatusBadgeClasses = (status: ToolCall['status']) => {\n switch (status) {\n case 'pending':\n return 'bg-muted text-muted-foreground';\n case 'running':\n return 'bg-blue-100 text-blue-700 dark:bg-blue-900 dark:text-blue-300';\n case 'completed':\n return 'bg-green-100 text-green-700 dark:bg-green-900 dark:text-green-300';\n case 'failed':\n return 'bg-red-100 text-red-700 dark:bg-red-900 dark:text-red-300';\n }\n };\n\n return (\n <div className=\"space-y-2\">\n <div className=\"flex items-center gap-2 text-xs uppercase tracking-wide text-muted-foreground font-semibold\">\n <Wrench className=\"h-3 w-3\" />\n {label || 'Ferramenta utilizada'}\n </div>\n {toolCalls.map((call) => {\n const isExpanded = expandedCall === call.id;\n const ToggleIcon = isExpanded ? ChevronDown : ChevronRight;\n\n return (\n <Card key={call.id} className=\"border border-dashed border-primary/40 bg-card/60\">\n <button\n type=\"button\"\n className=\"flex w-full items-center justify-between gap-3 px-3 py-2 text-left\"\n onClick={() => setExpandedCall(isExpanded ? null : call.id)}\n >\n <div className=\"flex items-center gap-2\">\n {getStatusIcon(call.status)}\n <span className=\"font-medium text-sm\">{call.name}</span>\n <Badge variant=\"secondary\" className={getStatusBadgeClasses(call.status)}>\n {call.status}\n </Badge>\n </div>\n <ToggleIcon className=\"h-4 w-4 text-muted-foreground\" />\n </button>\n {isExpanded && (\n <CardContent className=\"pt-0 pb-3 px-3 text-xs space-y-2\">\n <div>\n <div className=\"font-medium text-muted-foreground mb-1\">Args</div>\n <pre className=\"rounded bg-muted p-2 overflow-x-auto text-xs\">\n {JSON.stringify(call.arguments, null, 2)}\n </pre>\n </div>\n {typeof call.result !== 'undefined' && (\n <div>\n <div className=\"font-medium text-muted-foreground mb-1\">Result</div>\n <pre className=\"rounded bg-muted p-2 overflow-x-auto text-xs\">\n {JSON.stringify(call.result, null, 2)}\n </pre>\n </div>\n )}\n {call.startTime && call.endTime && (\n <div className=\"text-muted-foreground\">\n Executed in {call.endTime - call.startTime}ms\n </div>\n )}\n </CardContent>\n )}\n </Card>\n );\n })}\n </div>\n );\n});\n\n// Keep memo comparison lightweight. Message objects are treated immutably by the\n// chat state, so reference equality is enough to detect actual message changes.\nconst arePropsEqual = (prevProps: MessageProps, nextProps: MessageProps): boolean => {\n if (prevProps.message !== nextProps.message) return false;\n \n // Compare other props\n if (prevProps.isUser !== nextProps.isUser) return false;\n if (prevProps.userAvatar !== nextProps.userAvatar) return false;\n if (prevProps.userName !== nextProps.userName) return false;\n if (prevProps.assistantName !== nextProps.assistantName) return false;\n if (prevProps.showTimestamp !== nextProps.showTimestamp) return false;\n if (prevProps.showAvatar !== nextProps.showAvatar) return false;\n if (prevProps.enableCopy !== nextProps.enableCopy) return false;\n if (prevProps.enableEdit !== nextProps.enableEdit) return false;\n if (prevProps.enableRegenerate !== nextProps.enableRegenerate) return false;\n if (prevProps.enableToolCallsDisplay !== nextProps.enableToolCallsDisplay) return false;\n if (prevProps.compactMode !== nextProps.compactMode) return false;\n if (prevProps.className !== nextProps.className) return false;\n if (prevProps.toolUsedLabel !== nextProps.toolUsedLabel) return false;\n if (prevProps.thinkingLabel !== nextProps.thinkingLabel) return false;\n if (prevProps.showMoreLabel !== nextProps.showMoreLabel) return false;\n if (prevProps.showLessLabel !== nextProps.showLessLabel) return false;\n if (prevProps.collapseLongMessages !== nextProps.collapseLongMessages) return false;\n if (prevProps.collapseLongMessagesForUserOnly !== nextProps.collapseLongMessagesForUserOnly) return false;\n if (prevProps.longMessagePreviewChars !== nextProps.longMessagePreviewChars) return false;\n if (prevProps.longMessageChunkChars !== nextProps.longMessageChunkChars) return false;\n if (prevProps.renderUserMarkdown !== nextProps.renderUserMarkdown) return false;\n if (prevProps.markdown !== nextProps.markdown) return false;\n if (prevProps.isExpanded !== nextProps.isExpanded) return false;\n if (prevProps.onToggleExpanded !== nextProps.onToggleExpanded) return false;\n if (prevProps.isGrouped !== nextProps.isGrouped) return false;\n if (prevProps.assistantAvatar !== nextProps.assistantAvatar) return false;\n \n return true;\n};\n\nexport const Message: React.FC<MessageProps> = memo(({\n message,\n isUser,\n userAvatar,\n userName = 'Você',\n assistantAvatar,\n assistantName = 'Assistente',\n showTimestamp = false,\n showAvatar = true,\n enableCopy = true,\n enableEdit = true,\n enableRegenerate = true,\n enableToolCallsDisplay = false,\n compactMode = false,\n onAction,\n className = '',\n toolUsedLabel,\n thinkingLabel = 'Thinking...',\n showMoreLabel = 'Show more',\n showLessLabel = 'Show less',\n collapseLongMessages = false,\n collapseLongMessagesForUserOnly = false,\n longMessagePreviewChars = 4000,\n longMessageChunkChars = 12000,\n renderUserMarkdown = true,\n markdown,\n isExpanded = false,\n onToggleExpanded,\n isGrouped = false,\n agentOptions = [],\n}) => {\n const [isEditing, setIsEditing] = useState(false);\n const [editContent, setEditContent] = useState(message.content);\n const [showActions, setShowActions] = useState(false);\n const [copied, setCopied] = useState(false);\n\n const messageIsUser = isUser ?? message.role === 'user';\n\n // Resolve multi-agent sender display\n const agentSender = !messageIsUser && message.senderAgentId\n ? agentOptions.find(a =>\n a.id === message.senderAgentId ||\n a.name.toLowerCase() === (message.senderAgentId ?? '').toLowerCase() ||\n a.name.toLowerCase() === (message.senderName ?? '').toLowerCase()\n )\n : undefined;\n const isMultiAgent = agentOptions.length > 1;\n const resolvedAssistantName = (isMultiAgent && (agentSender?.name || message.senderName)) || assistantName;\n const agentColor = agentSender ? (agentSender.color || getAgentColor(agentSender.id)) : undefined;\n const canEdit = enableEdit && messageIsUser;\n const canRegenerate = enableRegenerate && !messageIsUser;\n const normalizedPreviewChars = Math.max(longMessagePreviewChars, 1);\n const normalizedChunkChars = Math.max(longMessageChunkChars, 1);\n const previewOverride = typeof message.metadata?.previewContent === 'string'\n ? message.metadata.previewContent\n : undefined;\n const canCollapseMessage = collapseLongMessages\n && !message.isStreaming\n && message.content.length > normalizedPreviewChars\n && (!collapseLongMessagesForUserOnly || messageIsUser);\n const isCollapsed = canCollapseMessage && !isExpanded;\n const contentToRender = isCollapsed\n ? getCollapsedPreview(message.content, normalizedPreviewChars, previewOverride)\n : message.content;\n const shouldRenderMarkdown = !isCollapsed && (!messageIsUser || renderUserMarkdown);\n const shouldApplyLargeContentContainment = !isCollapsed && message.content.length > normalizedChunkChars;\n const contentStyle: React.CSSProperties | undefined = shouldApplyLargeContentContainment\n ? {\n contentVisibility: 'auto',\n containIntrinsicSize: '1px 400px',\n }\n : undefined;\n const horizontalOffsetClass = showAvatar\n ? messageIsUser\n ? (compactMode ? 'mr-9' : 'mr-11')\n : (compactMode ? 'ml-9' : 'ml-11')\n : '';\n\n const handleCopy = async () => {\n try {\n await navigator.clipboard.writeText(message.content);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n onAction?.({ action: 'copy', messageId: message.id, content: message.content });\n } catch (error) {\n console.error('Failed to copy message:', error);\n }\n };\n\n const handleEdit = () => {\n if (isEditing) {\n if (editContent.trim() !== message.content) {\n onAction?.({ action: 'edit', messageId: message.id, content: editContent.trim() });\n }\n setIsEditing(false);\n } else {\n setEditContent(message.content);\n setIsEditing(true);\n }\n };\n\n const handleCancelEdit = () => {\n setEditContent(message.content);\n setIsEditing(false);\n };\n\n const handleRegenerate = () => {\n onAction?.({ action: 'regenerate', messageId: message.id });\n };\n\n const handleToggleExpanded = () => {\n onToggleExpanded?.(message.id);\n };\n\n const formatTime = (timestamp: number) => {\n return new Date(timestamp).toLocaleTimeString('pt-BR', {\n hour: '2-digit',\n minute: '2-digit',\n });\n };\n\n return (\n <div\n className={`flex w-full flex-col ${className} max-w-[800px] mx-auto`}\n onMouseEnter={() => setShowActions(true)}\n onMouseLeave={() => setShowActions(false)}\n >\n\n {/* Header row with avatar and name - hidden when grouped */}\n {!isGrouped && (\n <div className={`flex gap-3 ${messageIsUser ? 'flex-row-reverse' : 'flex-row'} w-full mb-1`}>\n {/* Avatar */}\n {showAvatar && (\n <div className={`flex-shrink-0 ${compactMode ? 'mt-1' : 'mt-0'}`}>\n <Avatar className={compactMode ? 'h-6 w-6' : 'h-8 w-8'}>\n {messageIsUser ? (\n <>\n <AvatarImage src={userAvatar} alt={userName} />\n <AvatarFallback className=\"bg-primary text-primary-foreground\">\n {userName.charAt(0).toUpperCase()}\n </AvatarFallback>\n </>\n ) : agentSender ? (\n <>\n {agentSender.avatarUrl ? (\n <AvatarImage src={agentSender.avatarUrl} alt={agentSender.name} />\n ) : null}\n <AvatarFallback\n style={agentColor ? { backgroundColor: agentColor, color: 'white' } : undefined}\n className={agentColor ? 'text-[10px]' : 'bg-secondary text-secondary-foreground'}\n >\n {getAgentInitials(agentSender.name)}\n </AvatarFallback>\n </>\n ) : (\n <>\n {assistantAvatar || (\n <AvatarFallback className=\"bg-secondary text-secondary-foreground\">\n AI\n </AvatarFallback>\n )}\n </>\n )}\n </Avatar>\n </div>\n )}\n\n {/* Header */}\n <div className={`flex items-center gap-2 mb-1 ${messageIsUser ? 'flex-row-reverse' : 'flex-row'}`}>\n <span\n className={`font-medium ${compactMode ? 'text-sm' : 'text-base'}`}\n style={!messageIsUser && agentColor ? { color: agentColor } : undefined}\n >\n {messageIsUser ? userName : resolvedAssistantName}\n </span>\n {showTimestamp && (\n <span className=\"text-xs text-muted-foreground\">\n {formatTime(message.timestamp)}\n </span>\n )}\n {message.isEdited && (\n <Badge variant=\"outline\" className=\"text-xs\">\n editado\n </Badge>\n )}\n </div>\n </div>\n )}\n\n {/* Keep body alignment consistent across grouped and ungrouped messages */}\n <div className={`flex-1 min-w-0 ${messageIsUser ? 'text-right' : 'text-left'} ${horizontalOffsetClass}`}>\n\n {/* Message Body */}\n <div className={`relative inline-flex flex-col overflow-hidden text-left ${messageIsUser\n ? 'rounded-lg p-3 bg-primary text-primary-foreground ml-auto max-w-[85%]'\n : 'max-w-full'\n }`}>\n {isEditing ? (\n <div className=\"space-y-2\">\n <Textarea\n value={editContent}\n onChange={(e) => setEditContent(e.target.value)}\n className=\"min-h-[100px] resize-none\"\n autoFocus\n />\n <div className=\"flex gap-2 justify-end\">\n <Button variant=\"outline\" size=\"sm\" onClick={handleCancelEdit}>\n <X className=\"h-4 w-4 mr-1\" />\n Cancelar\n </Button>\n <Button size=\"sm\" onClick={handleEdit}>\n <Check className=\"h-4 w-4 mr-1\" />\n Salvar\n </Button>\n </div>\n </div>\n ) : (\n <>\n {/* Reasoning/Thinking Block */}\n {!messageIsUser && message.reasoning && (\n <ThinkingBlock\n reasoning={message.reasoning}\n isStreaming={message.isReasoningStreaming}\n label={thinkingLabel}\n />\n )}\n\n {/* Tool Calls */}\n {enableToolCallsDisplay && message.toolCalls && message.toolCalls.length > 0 && (\n <div className=\"mb-3\">\n <ToolCallsDisplay toolCalls={message.toolCalls} label={toolUsedLabel} />\n </div>\n )}\n\n <StreamingText\n content={contentToRender}\n isStreaming={message.isStreaming}\n thinkingLabel={thinkingLabel}\n renderMarkdown={shouldRenderMarkdown}\n markdown={markdown}\n plainTextChunkChars={normalizedChunkChars}\n contentStyle={contentStyle}\n hideThinkingIndicator={!!message.reasoning}\n />\n\n {canCollapseMessage && (\n <div className=\"mt-3\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-auto px-0 text-xs font-medium text-current hover:bg-transparent hover:opacity-80\"\n aria-expanded={!isCollapsed}\n onClick={handleToggleExpanded}\n >\n {isCollapsed ? showMoreLabel : showLessLabel}\n </Button>\n </div>\n )}\n\n {/* Attachments */}\n {message.attachments && message.attachments.length > 0 && (\n <div className=\"mt-3 space-y-2\">\n {message.attachments.map((attachment, index) => (\n <MediaRenderer key={index} attachment={attachment} />\n ))}\n </div>\n )}\n </>\n )}\n\n {/* Action Buttons */}\n {!isEditing && (showActions || copied) && (\n <div className={`absolute -top-2 flex gap-1 ${messageIsUser ? '-left-2' : '-right-2'\n }`}>\n {enableCopy && (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"secondary\"\n size=\"icon\"\n className=\"h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity\"\n onClick={handleCopy}\n >\n {copied ? (\n <Check className=\"h-3 w-3 text-green-500\" />\n ) : (\n <Copy className=\"h-3 w-3\" />\n )}\n </Button>\n </TooltipTrigger>\n <TooltipContent>\n {copied ? 'Copiado!' : 'Copiar'}\n </TooltipContent>\n </Tooltip>\n )}\n\n {canEdit && (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"secondary\"\n size=\"icon\"\n className=\"h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity\"\n onClick={handleEdit}\n >\n <Edit className=\"h-3 w-3\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>\n Editar\n </TooltipContent>\n </Tooltip>\n )}\n\n {canRegenerate && (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"secondary\"\n size=\"icon\"\n className=\"h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity\"\n onClick={handleRegenerate}\n >\n <RotateCcw className=\"h-3 w-3\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>\n Regenerar\n </TooltipContent>\n </Tooltip>\n )}\n </div>\n )}\n </div>\n </div>\n </div>\n );\n}, arePropsEqual);\n","import { ChatMessage, ChatThread, MediaAttachment, AgentOption } from '../types/chatTypes';\n\nexport const chatUtils = {\n generateId: (): string => \n (globalThis.crypto?.randomUUID?.() ?? `id-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`),\n\n generateMessageId: (): string => chatUtils.generateId(),\n generateThreadId: (): string => chatUtils.generateId(),\n \n createMessage: (\n role: 'user' | 'assistant' | 'system',\n content: string,\n attachments?: MediaAttachment[]\n ): ChatMessage => ({\n id: chatUtils.generateMessageId(),\n role,\n content,\n timestamp: Date.now(),\n attachments,\n isComplete: true,\n }),\n\n createThread: (title: string): ChatThread => ({\n id: chatUtils.generateThreadId(),\n title,\n createdAt: Date.now(),\n updatedAt: Date.now(),\n messageCount: 0,\n }),\n\n generateThreadTitle: (firstMessage: string): string => {\n const cleaned = firstMessage.replace(/[^\\w\\s]/g, '').trim();\n const words = cleaned.split(/\\s+/).slice(0, 6);\n return words.join(' ') || 'Nova Conversa';\n },\n};\n\n// ============================================================================\n// Multi-agent color/display utilities\n// ============================================================================\n\nconst AGENT_COLORS = [\n '#6366f1', // indigo\n '#8b5cf6', // violet\n '#ec4899', // pink\n '#f59e0b', // amber\n '#10b981', // emerald\n '#3b82f6', // blue\n '#ef4444', // red\n '#14b8a6', // teal\n '#f97316', // orange\n '#84cc16', // lime\n];\n\n/** Deterministic color for an agent based on its ID. */\nexport function getAgentColor(agentId: string): string {\n let hash = 0;\n for (let i = 0; i < agentId.length; i++) {\n hash = ((hash << 5) - hash + agentId.charCodeAt(i)) | 0;\n }\n return AGENT_COLORS[Math.abs(hash) % AGENT_COLORS.length];\n}\n\n/** Up to 2-letter initials from an agent name. */\nexport function getAgentInitials(name: string): string {\n const parts = name.trim().split(/\\s+/);\n if (parts.length >= 2) {\n return (parts[0][0] + parts[1][0]).toUpperCase();\n }\n return name.slice(0, 2).toUpperCase();\n}\n\n/** Assign colors to agents that don't have a custom color. Returns a new array. */\nexport function assignAgentColors(agents: AgentOption[]): (AgentOption & { color: string })[] {\n return agents.map((agent) => ({\n ...agent,\n color: agent.color || getAgentColor(agent.id),\n }));\n}\n\n","import * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"../../lib/utils\"\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n {\n variants: {\n variant: {\n default:\n \"bg-primary text-primary-foreground shadow-xs hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n outline:\n \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n secondary:\n \"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80\",\n ghost:\n \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n icon: \"size-9\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction Button({\n className,\n variant,\n size,\n asChild = false,\n ...props\n}: React.ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean\n }) {\n const Comp = asChild ? Slot : \"button\"\n\n return (\n <Comp\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n )\n}\n\nexport { Button, buttonVariants }\n","import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\nimport type { ChatConfig } from \"../types/chatTypes\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n\nexport const formatDate = (timestamp: number, labels?: ChatConfig['labels']) => {\n const date = new Date(timestamp);\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));\n\n if (diffDays === 0) {\n return labels?.today || 'Today';\n } else if (diffDays === 1) {\n return labels?.yesterday || 'Yesterday';\n } else if (diffDays < 7) {\n return `${diffDays} ${labels?.daysAgo || 'days ago'}`;\n } else {\n return date.toLocaleDateString('en-US', {\n day: '2-digit',\n month: 'short',\n });\n }\n};\n\nexport const createObjectUrlFromDataUrl = (dataUrl: string): string | null => {\n const match = dataUrl.match(/^data:(.+?);base64,(.+)$/s);\n if (!match) {\n return null;\n }\n\n try {\n const [, mimeType, base64] = match;\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n\n for (let i = 0; i < binary.length; i += 1) {\n bytes[i] = binary.charCodeAt(i);\n }\n\n const blob = new Blob([bytes], { type: mimeType || 'application/octet-stream' });\n return URL.createObjectURL(blob);\n } catch {\n return null;\n }\n};\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as AvatarPrimitive from \"@radix-ui/react-avatar\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Avatar({\n className,\n ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Root>) {\n return (\n <AvatarPrimitive.Root\n data-slot=\"avatar\"\n className={cn(\n \"relative flex size-8 shrink-0 overflow-hidden rounded-full\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction AvatarImage({\n className,\n ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Image>) {\n return (\n <AvatarPrimitive.Image\n data-slot=\"avatar-image\"\n className={cn(\"aspect-square size-full\", className)}\n {...props}\n />\n )\n}\n\nfunction AvatarFallback({\n className,\n ...props\n}: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {\n return (\n <AvatarPrimitive.Fallback\n data-slot=\"avatar-fallback\"\n className={cn(\n \"bg-muted flex size-full items-center justify-center rounded-full\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Avatar, AvatarImage, AvatarFallback }\n","import * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"../../lib/utils\"\n\nconst badgeVariants = cva(\n \"inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden\",\n {\n variants: {\n variant: {\n default:\n \"border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90\",\n secondary:\n \"border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90\",\n destructive:\n \"border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n outline:\n \"text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nfunction Badge({\n className,\n variant,\n asChild = false,\n ...props\n}: React.ComponentProps<\"span\"> &\n VariantProps<typeof badgeVariants> & { asChild?: boolean }) {\n const Comp = asChild ? Slot : \"span\"\n\n return (\n <Comp\n data-slot=\"badge\"\n className={cn(badgeVariants({ variant }), className)}\n {...props}\n />\n )\n}\n\nexport { Badge, badgeVariants }\n","import * as React from \"react\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Card({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card\"\n className={cn(\n \"bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-header\"\n className={cn(\n \"@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-title\"\n className={cn(\"leading-none font-semibold\", className)}\n {...props}\n />\n )\n}\n\nfunction CardDescription({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-description\"\n className={cn(\"text-muted-foreground text-sm\", className)}\n {...props}\n />\n )\n}\n\nfunction CardAction({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-action\"\n className={cn(\n \"col-start-2 row-span-2 row-start-1 self-start justify-self-end\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-content\"\n className={cn(\"px-6\", className)}\n {...props}\n />\n )\n}\n\nfunction CardFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-footer\"\n className={cn(\"flex items-center px-6 [.border-t]:pt-6\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Card,\n CardHeader,\n CardFooter,\n CardTitle,\n CardAction,\n CardDescription,\n CardContent,\n}\n","import * as React from \"react\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Textarea({ className, ...props }: React.ComponentProps<\"textarea\">) {\n return (\n <textarea\n data-slot=\"textarea\"\n className={cn(\n \"border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Textarea }\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as TooltipPrimitive from \"@radix-ui/react-tooltip\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction TooltipProvider({\n delayDuration = 0,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {\n return (\n <TooltipPrimitive.Provider\n data-slot=\"tooltip-provider\"\n delayDuration={delayDuration}\n {...props}\n />\n )\n}\n\nfunction Tooltip({\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Root>) {\n return (\n <TooltipProvider>\n <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n </TooltipProvider>\n )\n}\n\nfunction TooltipTrigger({\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />\n}\n\nfunction TooltipContent({\n className,\n sideOffset = 0,\n children,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Content>) {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n data-slot=\"tooltip-content\"\n sideOffset={sideOffset}\n className={cn(\n \"bg-primary text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance\",\n className\n )}\n {...props}\n >\n {children}\n <TooltipPrimitive.Arrow className=\"bg-primary fill-primary z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]\" />\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n )\n}\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }\n","import React, { useState, useRef, useEffect } from 'react';\nimport { ChatThread } from '../../types/chatTypes';\nimport { Button } from '../ui/button';\nimport { Input } from '../ui/input';\nimport {\n Sidebar as ShadcnSidebar,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarHeader,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarRail,\n useSidebar,\n} from '../ui/sidebar';\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from '../ui/dialog';\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from '../ui/alert-dialog';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '../ui/dropdown-menu';\nimport {\n Plus,\n MoreHorizontal,\n Edit2,\n Trash2,\n Archive,\n Search,\n Filter,\n Bot,\n} from 'lucide-react';\nimport { UserMenu, UserMenuUser, UserMenuCallbacks, UserMenuConfig } from './UserMenu';\nimport { Avatar, AvatarFallback } from '../ui/avatar';\n\nexport interface SidebarConfig {\n labels?: {\n newChat?: string;\n search?: string;\n customComponentLabel?: string;\n showArchived?: string;\n hideArchived?: string;\n noThreadsFound?: string;\n noThreadsYet?: string;\n deleteConfirmTitle?: string;\n deleteConfirmDescription?: string;\n renameThread?: string;\n archiveThread?: string;\n unarchiveThread?: string;\n deleteThread?: string;\n today?: string;\n yesterday?: string;\n createNewThread?: string;\n threadNamePlaceholder?: string;\n cancel?: string;\n create?: string;\n daysAgo?: string;\n };\n branding?: {\n logo?: React.ReactNode;\n title?: React.ReactNode;\n subtitle?: React.ReactNode;\n };\n userMenu?: UserMenuConfig;\n}\n\nexport interface SidebarProps extends React.ComponentProps<typeof ShadcnSidebar> {\n threads: ChatThread[];\n currentThreadId?: string | null;\n config: SidebarConfig;\n onCreateThread?: (title?: string) => void;\n onSelectThread?: (threadId: string) => void;\n onRenameThread?: (threadId: string, newTitle: string) => void;\n onDeleteThread?: (threadId: string) => void;\n onArchiveThread?: (threadId: string) => void;\n // User menu props\n user?: UserMenuUser | null;\n userMenuCallbacks?: UserMenuCallbacks;\n currentTheme?: 'light' | 'dark' | 'system';\n showThemeOptions?: boolean;\n /** Additional items to render in the user menu */\n userMenuAdditionalItems?: React.ReactNode;\n}\n\n// Create thread dialog\nconst CreateThreadDialog: React.FC<{\n config: SidebarConfig;\n onCreateThread: (title?: string) => void;\n trigger?: React.ReactNode;\n}> = ({ config, onCreateThread, trigger }) => {\n const [title, setTitle] = useState('');\n const [isOpen, setIsOpen] = useState(false);\n\n const handleCreate = () => {\n onCreateThread(title.trim() || undefined);\n setTitle('');\n setIsOpen(false);\n };\n\n return (\n <Dialog open={isOpen} onOpenChange={setIsOpen}>\n <DialogTrigger asChild>\n {trigger || (\n <Button className=\"w-full justify-start\" variant=\"outline\">\n <Plus className=\"mr-2 h-4 w-4\" />\n {config.labels?.newChat || 'New Chat'}\n </Button>\n )}\n </DialogTrigger>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>{config.labels?.createNewThread || 'New Conversation'}</DialogTitle>\n <DialogDescription>\n Give your new conversation a name or leave blank to auto-generate one.\n </DialogDescription>\n </DialogHeader>\n <Input\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n placeholder={config.labels?.threadNamePlaceholder || \"Conversation name\"}\n onKeyDown={(e) => e.key === 'Enter' && handleCreate()}\n autoFocus\n />\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => setIsOpen(false)}>\n {config.labels?.cancel || 'Cancel'}\n </Button>\n <Button onClick={handleCreate}>\n {config.labels?.create || 'Create'}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n};\n\nconst ThreadInitialsIcon = ({ title }: { title: string }) => {\n const initials = title\n ?.split(' ')\n .map((n) => n[0])\n .slice(0, 2)\n .join('')\n .toUpperCase() || '?';\n \n return (\n <div className=\"flex shrink-0 items-center justify-center rounded bg-muted text-[10px] font-medium\">\n {initials}\n </div>\n );\n};\n\nexport const Sidebar: React.FC<SidebarProps> = ({\n threads,\n currentThreadId,\n config,\n onCreateThread,\n onSelectThread,\n onRenameThread,\n onDeleteThread,\n onArchiveThread,\n // User menu props\n user,\n userMenuCallbacks,\n currentTheme,\n showThemeOptions = true,\n userMenuAdditionalItems,\n ...props\n}) => {\n const [searchQuery, setSearchQuery] = useState('');\n const [showArchived, setShowArchived] = useState(false);\n const [deleteThreadId, setDeleteThreadId] = useState<string | null>(null);\n const [editingThreadId, setEditingThreadId] = useState<string | null>(null);\n const [editTitle, setEditTitle] = useState('');\n const inputRef = useRef<HTMLInputElement>(null);\n \n // Use the sidebar context to control expansion\n const { setOpen } = useSidebar();\n\n useEffect(() => {\n if (editingThreadId && inputRef.current) {\n inputRef.current.focus();\n inputRef.current.select();\n }\n }, [editingThreadId]);\n\n // Filter threads based on search and archive filter\n const filteredThreads = threads.filter(thread => {\n const title = (thread.title ?? '').toString();\n const matchesSearch = title.toLowerCase().includes(searchQuery.toLowerCase());\n const matchesArchiveFilter = showArchived || !thread.isArchived;\n return matchesSearch && matchesArchiveFilter;\n });\n\n // Group threads by date\n const groupedThreads = filteredThreads.reduce((groups, thread) => {\n const date = new Date(thread.updatedAt);\n const today = new Date();\n const yesterday = new Date(today.getTime() - 24 * 60 * 60 * 1000);\n\n let groupKey: string;\n if (date.toDateString() === today.toDateString()) {\n groupKey = config.labels?.today || 'Today';\n } else if (date.toDateString() === yesterday.toDateString()) {\n groupKey = config.labels?.yesterday || 'Yesterday';\n } else {\n groupKey = date.toLocaleDateString('en-US', {\n weekday: 'long',\n day: '2-digit',\n month: 'long',\n });\n }\n\n if (!groups[groupKey]) {\n groups[groupKey] = [];\n }\n groups[groupKey].push(thread);\n return groups;\n }, {} as Record<string, ChatThread[]>);\n\n const handleDeleteThread = (threadId: string) => {\n onDeleteThread?.(threadId);\n setDeleteThreadId(null);\n };\n\n const startEditing = (thread: ChatThread) => {\n setEditingThreadId(thread.id);\n setEditTitle(thread.title || '');\n };\n\n const saveEdit = () => {\n if (editingThreadId && editTitle.trim()) {\n onRenameThread?.(editingThreadId, editTitle.trim());\n }\n setEditingThreadId(null);\n };\n\n const cancelEdit = () => {\n setEditingThreadId(null);\n };\n\n return (\n <ShadcnSidebar collapsible=\"icon\" {...props}>\n <SidebarHeader>\n {/* Branding / Logo */}\n <div className=\"flex items-center gap-3 px-2 py-3\">\n <div className=\"flex items-center justify-center shrink-0\">\n {config.branding?.logo || (\n <Avatar className=\"h-8 w-8\">\n <AvatarFallback className=\"bg-primary text-primary-foreground\">\n <Bot className=\"h-4 w-4\" />\n </AvatarFallback>\n </Avatar>\n )}\n </div>\n <div className=\"flex flex-col min-w-0 group-data-[collapsible=icon]:hidden\">\n <span className=\"text-sm font-semibold truncate\">\n {config.branding?.title || 'Chat'}\n </span>\n {config.branding?.subtitle && (\n <span className=\"text-xs text-muted-foreground truncate\">\n {config.branding.subtitle}\n </span>\n )}\n </div>\n </div>\n\n {/* New Chat Button */}\n {onCreateThread && (\n <CreateThreadDialog \n config={config} \n onCreateThread={onCreateThread} \n trigger={\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton\n size=\"lg\"\n className=\"w-full justify-start gap-2 border border-sidebar-border shadow-sm hover:bg-sidebar-accent hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:justify-center\"\n tooltip={config.labels?.newChat || 'New Chat'}\n >\n <Plus className=\"size-4\" />\n <span className=\"group-data-[collapsible=icon]:hidden\">{config.labels?.newChat || 'New Chat'}</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n }\n />\n )}\n \n {/* Search */}\n <div className=\"px-2 py-1 mt-4\">\n {/* Expanded View: Input */}\n <div className=\"relative group-data-[collapsible=icon]:hidden\">\n <Search className=\"pointer-events-none absolute left-2 top-1/2 size-4 -translate-y-1/2 select-none opacity-50\" />\n <Input\n className=\"pl-8 h-8 bg-sidebar-accent/50 border-sidebar-border focus-visible:ring-1 focus-visible:ring-sidebar-ring\"\n placeholder={config.labels?.search || \"Search...\"}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n />\n </div>\n \n {/* Collapsed View: Search Icon Button (expands sidebar on click) */}\n <div className=\"hidden group-data-[collapsible=icon]:flex justify-center\">\n <Button \n variant=\"ghost\" \n size=\"icon\" \n className=\"h-7 w-7\" \n onClick={() => setOpen(true)}\n title={config.labels?.search || \"Search\"}\n >\n <Search className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n </SidebarHeader>\n\n <SidebarContent>\n {/* Archive Filter Toggle (if needed) */}\n {threads.some(t => t.isArchived) && (\n <div className=\"px-4 py-2 mt-2 group-data-[collapsible=icon]:hidden\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setShowArchived(!showArchived)}\n className=\"h-6 text-xs w-full justify-start text-muted-foreground\"\n >\n <Filter className=\"mr-2 h-3 w-3\" />\n {showArchived ? \n (config.labels?.hideArchived || 'Hide Archived') : \n (config.labels?.showArchived || 'Show Archived')\n }\n </Button>\n </div>\n )}\n\n {Object.keys(groupedThreads).length === 0 ? (\n <div className=\"px-4 py-8 text-center text-muted-foreground group-data-[collapsible=icon]:hidden\">\n <div className=\"mx-auto h-8 w-8 mb-2 flex items-center justify-center rounded-full bg-muted/50\">\n <Plus className=\"h-4 w-4 opacity-50\" />\n </div>\n <p className=\"text-xs\">\n {searchQuery ? \n (config.labels?.noThreadsFound || 'No conversations found') : \n (config.labels?.noThreadsYet || 'No conversations yet')\n }\n </p>\n </div>\n ) : (\n Object.entries(groupedThreads).map(([group, groupThreads]) => (\n <SidebarGroup className=\"mt-2\" key={group}>\n <SidebarGroupLabel className=\"group-data-[collapsible=icon]:hidden\">{group}</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu>\n {groupThreads.map((thread) => (\n <SidebarMenuItem key={thread.id}>\n {editingThreadId === thread.id ? (\n <div className=\"flex items-center gap-1 px-2 py-1\">\n <Input\n ref={inputRef}\n value={editTitle}\n onChange={(e) => setEditTitle(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') saveEdit();\n if (e.key === 'Escape') cancelEdit();\n }}\n onBlur={saveEdit}\n className=\"h-7 text-sm\"\n />\n </div>\n ) : (\n <SidebarMenuButton\n isActive={currentThreadId === thread.id}\n onClick={() => onSelectThread?.(thread.id)}\n tooltip={thread.title}\n >\n <ThreadInitialsIcon title={thread.title || '?'} />\n <div className=\"flex flex-col items-start gap-0.5 flex-1 min-w-0 group-data-[collapsible=icon]:hidden\">\n <span className=\"truncate w-full\">{thread.title || 'New Chat'}</span>\n </div>\n {thread.isArchived && <Archive className=\"ml-auto h-3 w-3 opacity-50 group-data-[collapsible=icon]:hidden\" />}\n </SidebarMenuButton>\n )}\n \n {!editingThreadId && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <SidebarMenuAction showOnHover>\n <MoreHorizontal />\n <span className=\"sr-only\">More</span>\n </SidebarMenuAction>\n </DropdownMenuTrigger>\n <DropdownMenuContent className=\"w-48\" side=\"right\" align=\"start\">\n <DropdownMenuItem onClick={() => startEditing(thread)}>\n <Edit2 className=\"mr-2 h-4 w-4\" />\n <span>{config.labels?.renameThread || 'Rename'}</span>\n </DropdownMenuItem>\n <DropdownMenuItem onClick={() => onArchiveThread?.(thread.id)}>\n <Archive className=\"mr-2 h-4 w-4\" />\n <span>\n {thread.isArchived ? \n (config.labels?.unarchiveThread || 'Unarchive') : \n (config.labels?.archiveThread || 'Archive')\n }\n </span>\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem \n onClick={() => setDeleteThreadId(thread.id)}\n className=\"text-destructive focus:text-destructive\"\n >\n <Trash2 className=\"mr-2 h-4 w-4\" />\n <span>{config.labels?.deleteThread || 'Delete'}</span>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n </SidebarMenuItem>\n ))}\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n ))\n )}\n </SidebarContent>\n \n <SidebarFooter>\n <UserMenu\n user={user}\n config={config.userMenu}\n callbacks={userMenuCallbacks}\n currentTheme={currentTheme}\n showThemeOptions={showThemeOptions}\n additionalItems={userMenuAdditionalItems}\n />\n </SidebarFooter>\n \n <SidebarRail />\n\n {/* Delete confirmation dialog - only render when needed to avoid Radix focus conflicts */}\n {deleteThreadId && (\n <AlertDialog open={!!deleteThreadId} onOpenChange={() => setDeleteThreadId(null)}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>{config.labels?.deleteConfirmTitle || 'Delete Conversation'}</AlertDialogTitle>\n <AlertDialogDescription>\n {config.labels?.deleteConfirmDescription ||\n 'Are you sure you want to delete this conversation? This action cannot be undone.'\n }\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>{config.labels?.cancel || 'Cancel'}</AlertDialogCancel>\n <AlertDialogAction\n onClick={() => deleteThreadId && handleDeleteThread(deleteThreadId)}\n className=\"bg-destructive text-destructive-foreground hover:bg-destructive/90\"\n >\n {config.labels?.deleteThread || 'Delete'}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n )}\n </ShadcnSidebar>\n );\n};\n","import * as React from \"react\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Input({ className, type, ...props }: React.ComponentProps<\"input\">) {\n return (\n <input\n type={type}\n data-slot=\"input\"\n className={cn(\n \"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm\",\n \"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]\",\n \"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Input }\n","import * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, VariantProps } from \"class-variance-authority\"\nimport { PanelLeftIcon } from \"lucide-react\"\n\nimport { useIsMobile } from \"../../hooks/use-mobile\"\nimport { cn } from \"../../lib/utils\"\nimport { Button } from \"./button\"\nimport { Input } from \"./input\"\nimport { Separator } from \"./separator\"\nimport {\n Sheet,\n SheetContent,\n SheetDescription,\n SheetHeader,\n SheetTitle,\n} from \"./sheet\"\nimport { Skeleton } from \"./skeleton\"\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"./tooltip\"\n\nconst SIDEBAR_COOKIE_NAME = \"sidebar_state\"\nconst SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7\nconst SIDEBAR_WIDTH = \"16rem\"\nconst SIDEBAR_WIDTH_MOBILE = \"18rem\"\nconst SIDEBAR_WIDTH_ICON = \"3rem\"\nconst SIDEBAR_KEYBOARD_SHORTCUT = \"b\"\n\ntype SidebarContextProps = {\n state: \"expanded\" | \"collapsed\"\n open: boolean\n setOpen: (open: boolean) => void\n openMobile: boolean\n setOpenMobile: (open: boolean) => void\n isMobile: boolean\n toggleSidebar: () => void\n}\n\nconst SidebarContext = React.createContext<SidebarContextProps | null>(null)\n\nfunction useSidebar() {\n const context = React.useContext(SidebarContext)\n if (!context) {\n throw new Error(\"useSidebar must be used within a SidebarProvider.\")\n }\n\n return context\n}\n\nfunction SidebarProvider({\n defaultOpen = true,\n open: openProp,\n onOpenChange: setOpenProp,\n className,\n style,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & {\n defaultOpen?: boolean\n open?: boolean\n onOpenChange?: (open: boolean) => void\n}) {\n const isMobile = useIsMobile()\n const [openMobile, setOpenMobile] = React.useState(false)\n\n // This is the internal state of the sidebar.\n // We use openProp and setOpenProp for control from outside the component.\n const [_open, _setOpen] = React.useState(defaultOpen)\n const open = openProp ?? _open\n const setOpen = React.useCallback(\n (value: boolean | ((value: boolean) => boolean)) => {\n const openState = typeof value === \"function\" ? value(open) : value\n if (setOpenProp) {\n setOpenProp(openState)\n } else {\n _setOpen(openState)\n }\n\n // This sets the cookie to keep the sidebar state.\n document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`\n },\n [setOpenProp, open]\n )\n\n // Helper to toggle the sidebar.\n const toggleSidebar = React.useCallback(() => {\n return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open)\n }, [isMobile, setOpen, setOpenMobile])\n\n // Adds a keyboard shortcut to toggle the sidebar.\n React.useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (\n event.key === SIDEBAR_KEYBOARD_SHORTCUT &&\n (event.metaKey || event.ctrlKey)\n ) {\n event.preventDefault()\n toggleSidebar()\n }\n }\n\n window.addEventListener(\"keydown\", handleKeyDown)\n return () => window.removeEventListener(\"keydown\", handleKeyDown)\n }, [toggleSidebar])\n\n // We add a state so that we can do data-state=\"expanded\" or \"collapsed\".\n // This makes it easier to style the sidebar with Tailwind classes.\n const state = open ? \"expanded\" : \"collapsed\"\n\n const contextValue = React.useMemo<SidebarContextProps>(\n () => ({\n state,\n open,\n setOpen,\n isMobile,\n openMobile,\n setOpenMobile,\n toggleSidebar,\n }),\n [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar]\n )\n\n return (\n <SidebarContext.Provider value={contextValue}>\n <TooltipProvider delayDuration={0}>\n <div\n data-slot=\"sidebar-wrapper\"\n style={\n {\n \"--sidebar-width\": SIDEBAR_WIDTH,\n \"--sidebar-width-icon\": SIDEBAR_WIDTH_ICON,\n ...style,\n } as React.CSSProperties\n }\n className={cn(\n \"group/sidebar-wrapper has-data-[variant=inset]:bg-sidebar flex min-h-svh w-full\",\n className\n )}\n {...props}\n >\n {children}\n </div>\n </TooltipProvider>\n </SidebarContext.Provider>\n )\n}\n\nfunction Sidebar({\n side = \"left\",\n variant = \"sidebar\",\n collapsible = \"offcanvas\",\n className,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & {\n side?: \"left\" | \"right\"\n variant?: \"sidebar\" | \"floating\" | \"inset\"\n collapsible?: \"offcanvas\" | \"icon\" | \"none\"\n}) {\n \n const { isMobile, state, openMobile, setOpenMobile } = useSidebar()\n\n if (collapsible === \"none\") {\n return (\n <div\n data-slot=\"sidebar\"\n className={cn(\n \"bg-sidebar text-sidebar-foreground flex h-full w-(--sidebar-width) flex-col\",\n className\n )}\n {...props}\n >\n {children}\n </div>\n )\n }\n\n if (isMobile) {\n return (\n <Sheet open={openMobile} onOpenChange={setOpenMobile} {...props}>\n <SheetContent\n data-sidebar=\"sidebar\"\n data-slot=\"sidebar\"\n data-mobile=\"true\"\n className=\"bg-sidebar text-sidebar-foreground w-(--sidebar-width) p-0 [&>button]:hidden\"\n style={\n {\n \"--sidebar-width\": SIDEBAR_WIDTH_MOBILE,\n } as React.CSSProperties\n }\n side={side}\n >\n <SheetHeader className=\"sr-only\">\n <SheetTitle>Sidebar</SheetTitle>\n <SheetDescription>Displays the mobile sidebar.</SheetDescription>\n </SheetHeader>\n <div className=\"flex h-full w-full flex-col\">{children}</div>\n </SheetContent>\n </Sheet>\n )\n }\n\n return (\n <div\n className=\"group peer text-sidebar-foreground hidden md:block\"\n data-state={state}\n data-collapsible={state === \"collapsed\" ? collapsible : \"\"}\n data-variant={variant}\n data-side={side}\n data-slot=\"sidebar\"\n >\n {/* This is what handles the sidebar gap on desktop */}\n <div\n data-slot=\"sidebar-gap\"\n className={cn(\n \"relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear\",\n \"group-data-[collapsible=offcanvas]:w-0\",\n \"group-data-[side=right]:rotate-180\",\n variant === \"floating\" || variant === \"inset\"\n ? \"group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]\"\n : \"group-data-[collapsible=icon]:w-(--sidebar-width-icon)\"\n )}\n />\n <div\n data-slot=\"sidebar-container\"\n className={cn(\n \"fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:flex\",\n side === \"left\"\n ? \"left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]\"\n : \"right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]\",\n // Adjust the padding for floating and inset variants.\n variant === \"floating\" || variant === \"inset\"\n ? \"p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]\"\n : \"group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l\",\n className\n )}\n {...props}\n >\n <div\n data-sidebar=\"sidebar\"\n data-slot=\"sidebar-inner\"\n className=\"bg-sidebar group-data-[variant=floating]:border-sidebar-border flex h-full w-full flex-col group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:shadow-sm\"\n >\n {children}\n </div>\n </div>\n </div>\n )\n}\n\nfunction SidebarTrigger({\n className,\n onClick,\n ...props\n}: React.ComponentProps<typeof Button>) {\n const { toggleSidebar } = useSidebar()\n\n return (\n <Button\n data-sidebar=\"trigger\"\n data-slot=\"sidebar-trigger\"\n variant=\"ghost\"\n size=\"icon\"\n className={cn(\"size-7\", className)}\n onClick={(event) => {\n onClick?.(event)\n toggleSidebar()\n }}\n {...props}\n >\n <PanelLeftIcon />\n <span className=\"sr-only\">Toggle Sidebar</span>\n </Button>\n )\n}\n\nfunction SidebarRail({ className, ...props }: React.ComponentProps<\"button\">) {\n const { toggleSidebar } = useSidebar()\n\n return (\n <button\n data-sidebar=\"rail\"\n data-slot=\"sidebar-rail\"\n aria-label=\"Toggle Sidebar\"\n tabIndex={-1}\n onClick={toggleSidebar}\n title=\"Toggle Sidebar\"\n className={cn(\n \"hover:after:bg-sidebar-border absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] sm:flex\",\n \"in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize\",\n \"[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize\",\n \"hover:group-data-[collapsible=offcanvas]:bg-sidebar group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full\",\n \"[[data-side=left][data-collapsible=offcanvas]_&]:-right-2\",\n \"[[data-side=right][data-collapsible=offcanvas]_&]:-left-2\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarInset({ className, ...props }: React.ComponentProps<\"main\">) {\n return (\n <main\n data-slot=\"sidebar-inset\"\n className={cn(\n \"bg-background relative flex w-full flex-1 flex-col\",\n \"md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarInput({\n className,\n ...props\n}: React.ComponentProps<typeof Input>) {\n return (\n <Input\n data-slot=\"sidebar-input\"\n data-sidebar=\"input\"\n className={cn(\"bg-background h-8 w-full shadow-none\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-header\"\n data-sidebar=\"header\"\n className={cn(\"flex flex-col gap-2 p-2\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-footer\"\n data-sidebar=\"footer\"\n className={cn(\"flex flex-col gap-2 p-2\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof Separator>) {\n return (\n <Separator\n data-slot=\"sidebar-separator\"\n data-sidebar=\"separator\"\n className={cn(\"bg-sidebar-border mx-2 w-auto\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-content\"\n data-sidebar=\"content\"\n className={cn(\n \"flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-group\"\n data-sidebar=\"group\"\n className={cn(\"relative flex w-full min-w-0 flex-col p-2\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarGroupLabel({\n className,\n asChild = false,\n ...props\n}: React.ComponentProps<\"div\"> & { asChild?: boolean }) {\n const Comp = asChild ? Slot : \"div\"\n\n return (\n <Comp\n data-slot=\"sidebar-group-label\"\n data-sidebar=\"group-label\"\n className={cn(\n \"text-sidebar-foreground/70 ring-sidebar-ring flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium outline-hidden transition-[margin,opacity] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0\",\n \"group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarGroupAction({\n className,\n asChild = false,\n ...props\n}: React.ComponentProps<\"button\"> & { asChild?: boolean }) {\n const Comp = asChild ? Slot : \"button\"\n\n return (\n <Comp\n data-slot=\"sidebar-group-action\"\n data-sidebar=\"group-action\"\n className={cn(\n \"text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0\",\n // Increases the hit area of the button on mobile.\n \"after:absolute after:-inset-2 md:after:hidden\",\n \"group-data-[collapsible=icon]:hidden\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarGroupContent({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-group-content\"\n data-sidebar=\"group-content\"\n className={cn(\"w-full text-sm\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarMenu({ className, ...props }: React.ComponentProps<\"ul\">) {\n return (\n <ul\n data-slot=\"sidebar-menu\"\n data-sidebar=\"menu\"\n className={cn(\"flex w-full min-w-0 flex-col gap-1\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuItem({ className, ...props }: React.ComponentProps<\"li\">) {\n return (\n <li\n data-slot=\"sidebar-menu-item\"\n data-sidebar=\"menu-item\"\n className={cn(\"group/menu-item relative\", className)}\n {...props}\n />\n )\n}\n\nconst sidebarMenuButtonVariants = cva(\n \"peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-hidden ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0\",\n {\n variants: {\n variant: {\n default: \"hover:bg-sidebar-accent hover:text-sidebar-accent-foreground\",\n outline:\n \"bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]\",\n },\n size: {\n default: \"h-8 text-sm\",\n sm: \"h-7 text-xs\",\n lg: \"h-12 text-sm group-data-[collapsible=icon]:p-0!\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction SidebarMenuButton({\n asChild = false,\n isActive = false,\n variant = \"default\",\n size = \"default\",\n tooltip,\n className,\n ...props\n}: React.ComponentProps<\"button\"> & {\n asChild?: boolean\n isActive?: boolean\n tooltip?: string | React.ComponentProps<typeof TooltipContent>\n} & VariantProps<typeof sidebarMenuButtonVariants>) {\n const Comp = asChild ? Slot : \"button\"\n const { isMobile, state } = useSidebar()\n\n const button = (\n <Comp\n data-slot=\"sidebar-menu-button\"\n data-sidebar=\"menu-button\"\n data-size={size}\n data-active={isActive}\n className={cn(sidebarMenuButtonVariants({ variant, size }), className)}\n {...props}\n />\n )\n\n if (!tooltip) {\n return button\n }\n\n if (typeof tooltip === \"string\") {\n tooltip = {\n children: tooltip,\n }\n }\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>{button}</TooltipTrigger>\n <TooltipContent\n side=\"right\"\n align=\"center\"\n hidden={state !== \"collapsed\" || isMobile}\n {...tooltip}\n />\n </Tooltip>\n )\n}\n\nfunction SidebarMenuAction({\n className,\n asChild = false,\n showOnHover = false,\n ...props\n}: React.ComponentProps<\"button\"> & {\n asChild?: boolean\n showOnHover?: boolean\n}) {\n const Comp = asChild ? Slot : \"button\"\n\n return (\n <Comp\n data-slot=\"sidebar-menu-action\"\n data-sidebar=\"menu-action\"\n className={cn(\n \"text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground peer-hover/menu-button:text-sidebar-accent-foreground absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0\",\n // Increases the hit area of the button on mobile.\n \"after:absolute after:-inset-2 md:after:hidden\",\n \"peer-data-[size=sm]/menu-button:top-1\",\n \"peer-data-[size=default]/menu-button:top-1.5\",\n \"peer-data-[size=lg]/menu-button:top-2.5\",\n \"group-data-[collapsible=icon]:hidden\",\n showOnHover &&\n \"peer-data-[active=true]/menu-button:text-sidebar-accent-foreground group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 md:opacity-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuBadge({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-menu-badge\"\n data-sidebar=\"menu-badge\"\n className={cn(\n \"text-sidebar-foreground pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums select-none\",\n \"peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground\",\n \"peer-data-[size=sm]/menu-button:top-1\",\n \"peer-data-[size=default]/menu-button:top-1.5\",\n \"peer-data-[size=lg]/menu-button:top-2.5\",\n \"group-data-[collapsible=icon]:hidden\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuSkeleton({\n className,\n showIcon = false,\n ...props\n}: React.ComponentProps<\"div\"> & {\n showIcon?: boolean\n}) {\n // Random width between 50 to 90%.\n const width = React.useMemo(() => {\n return `${Math.floor(Math.random() * 40) + 50}%`\n }, [])\n\n return (\n <div\n data-slot=\"sidebar-menu-skeleton\"\n data-sidebar=\"menu-skeleton\"\n className={cn(\"flex h-8 items-center gap-2 rounded-md px-2\", className)}\n {...props}\n >\n {showIcon && (\n <Skeleton\n className=\"size-4 rounded-md\"\n data-sidebar=\"menu-skeleton-icon\"\n />\n )}\n <Skeleton\n className=\"h-4 max-w-(--skeleton-width) flex-1\"\n data-sidebar=\"menu-skeleton-text\"\n style={\n {\n \"--skeleton-width\": width,\n } as React.CSSProperties\n }\n />\n </div>\n )\n}\n\nfunction SidebarMenuSub({ className, ...props }: React.ComponentProps<\"ul\">) {\n return (\n <ul\n data-slot=\"sidebar-menu-sub\"\n data-sidebar=\"menu-sub\"\n className={cn(\n \"border-sidebar-border mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l px-2.5 py-0.5\",\n \"group-data-[collapsible=icon]:hidden\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuSubItem({\n className,\n ...props\n}: React.ComponentProps<\"li\">) {\n return (\n <li\n data-slot=\"sidebar-menu-sub-item\"\n data-sidebar=\"menu-sub-item\"\n className={cn(\"group/menu-sub-item relative\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuSubButton({\n asChild = false,\n size = \"md\",\n isActive = false,\n className,\n ...props\n}: React.ComponentProps<\"a\"> & {\n asChild?: boolean\n size?: \"sm\" | \"md\"\n isActive?: boolean\n}) {\n const Comp = asChild ? Slot : \"a\"\n\n return (\n <Comp\n data-slot=\"sidebar-menu-sub-button\"\n data-sidebar=\"menu-sub-button\"\n data-size={size}\n data-active={isActive}\n className={cn(\n \"text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground [&>svg]:text-sidebar-accent-foreground flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 outline-hidden focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0\",\n \"data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground\",\n size === \"sm\" && \"text-xs\",\n size === \"md\" && \"text-sm\",\n \"group-data-[collapsible=icon]:hidden\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupAction,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarHeader,\n SidebarInput,\n SidebarInset,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuBadge,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSkeleton,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n SidebarProvider,\n SidebarRail,\n SidebarSeparator,\n SidebarTrigger,\n useSidebar,\n}\n","import * as React from \"react\"\n\nconst MOBILE_BREAKPOINT = 768\n\nexport function useIsMobile() {\n const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined)\n\n React.useEffect(() => {\n const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)\n const onChange = () => {\n setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)\n }\n mql.addEventListener(\"change\", onChange)\n setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)\n return () => mql.removeEventListener(\"change\", onChange)\n }, [])\n\n return !!isMobile\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as SeparatorPrimitive from \"@radix-ui/react-separator\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Separator({\n className,\n orientation = \"horizontal\",\n decorative = true,\n ...props\n}: React.ComponentProps<typeof SeparatorPrimitive.Root>) {\n return (\n <SeparatorPrimitive.Root\n data-slot=\"separator\"\n decorative={decorative}\n orientation={orientation}\n className={cn(\n \"bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Separator }\n","import * as React from \"react\"\nimport * as SheetPrimitive from \"@radix-ui/react-dialog\"\nimport { XIcon } from \"lucide-react\"\n\nimport { cn } from \"../../lib/utils\"\n\n/**\n * Clean up body styles that Radix may leave behind.\n * This fixes an issue where pointer-events: none gets stuck on body.\n */\nfunction cleanupBodyStyles() {\n if (typeof document !== 'undefined' && document.body.style.pointerEvents === 'none') {\n document.body.style.pointerEvents = '';\n }\n}\n\nfunction Sheet({ open, onOpenChange, ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {\n // Track previous open state to detect close transition\n const prevOpenRef = React.useRef(open);\n\n React.useEffect(() => {\n // When transitioning from open to closed, ensure cleanup after animation\n if (prevOpenRef.current === true && open === false) {\n const timeout = setTimeout(cleanupBodyStyles, 350); // After close animation (300ms + buffer)\n return () => clearTimeout(timeout);\n }\n prevOpenRef.current = open;\n }, [open]);\n\n // Cleanup on unmount\n React.useEffect(() => {\n return () => {\n cleanupBodyStyles();\n };\n }, []);\n\n return <SheetPrimitive.Root data-slot=\"sheet\" open={open} onOpenChange={onOpenChange} {...props} />\n}\n\nfunction SheetTrigger({\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Trigger>) {\n return <SheetPrimitive.Trigger data-slot=\"sheet-trigger\" {...props} />\n}\n\nfunction SheetClose({\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Close>) {\n return <SheetPrimitive.Close data-slot=\"sheet-close\" {...props} />\n}\n\nfunction SheetPortal({\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Portal>) {\n return <SheetPrimitive.Portal data-slot=\"sheet-portal\" {...props} />\n}\n\nfunction SheetOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Overlay>) {\n return (\n <SheetPrimitive.Overlay\n data-slot=\"sheet-overlay\"\n className={cn(\n \"fixed inset-0 z-50 bg-black/50\",\n \"data-[state=open]:animate-in data-[state=closed]:animate-out\",\n \"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n \"data-[state=closed]:pointer-events-none\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SheetContent({\n className,\n children,\n side = \"right\",\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Content> & {\n side?: \"top\" | \"right\" | \"bottom\" | \"left\"\n}) {\n return (\n <SheetPortal>\n <SheetOverlay />\n <SheetPrimitive.Content\n data-slot=\"sheet-content\"\n aria-describedby={undefined}\n className={cn(\n \"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500\",\n side === \"right\" &&\n \"data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm\",\n side === \"left\" &&\n \"data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm\",\n side === \"top\" &&\n \"data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b\",\n side === \"bottom\" &&\n \"data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 h-auto border-t\",\n className\n )}\n {...props}\n >\n {children}\n <SheetPrimitive.Close className=\"ring-offset-background focus:ring-ring data-[state=open]:bg-secondary absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none\">\n <XIcon className=\"size-4\" />\n <span className=\"sr-only\">Close</span>\n </SheetPrimitive.Close>\n </SheetPrimitive.Content>\n </SheetPortal>\n )\n}\n\nfunction SheetHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sheet-header\"\n className={cn(\"flex flex-col gap-1.5 p-4\", className)}\n {...props}\n />\n )\n}\n\nfunction SheetFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sheet-footer\"\n className={cn(\"mt-auto flex flex-col gap-2 p-4\", className)}\n {...props}\n />\n )\n}\n\nfunction SheetTitle({\n className,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Title>) {\n return (\n <SheetPrimitive.Title\n data-slot=\"sheet-title\"\n className={cn(\"text-foreground font-semibold\", className)}\n {...props}\n />\n )\n}\n\nfunction SheetDescription({\n className,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Description>) {\n return (\n <SheetPrimitive.Description\n data-slot=\"sheet-description\"\n className={cn(\"text-muted-foreground text-sm\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Sheet,\n SheetTrigger,\n SheetClose,\n SheetContent,\n SheetHeader,\n SheetFooter,\n SheetTitle,\n SheetDescription,\n}\n","import { cn } from \"../../lib/utils\"\n\nfunction Skeleton({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"skeleton\"\n className={cn(\"bg-accent animate-pulse rounded-md\", className)}\n {...props}\n />\n )\n}\n\nexport { Skeleton }\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as DialogPrimitive from \"@radix-ui/react-dialog\"\nimport { XIcon } from \"lucide-react\"\n\nimport { cn } from \"../../lib/utils\"\n\n/**\n * Clean up body styles that Radix may leave behind.\n * This fixes an issue where pointer-events: none gets stuck on body.\n */\nfunction cleanupBodyStyles() {\n if (typeof document !== 'undefined' && document.body.style.pointerEvents === 'none') {\n document.body.style.pointerEvents = '';\n }\n}\n\nfunction Dialog({\n open,\n onOpenChange,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Root>) {\n // Track previous open state to detect close transition\n const prevOpenRef = React.useRef(open);\n\n React.useEffect(() => {\n // When transitioning from open to closed, ensure cleanup after animation\n if (prevOpenRef.current === true && open === false) {\n const timeout = setTimeout(cleanupBodyStyles, 250); // After close animation (200ms + buffer)\n return () => clearTimeout(timeout);\n }\n prevOpenRef.current = open;\n }, [open]);\n\n // Cleanup on unmount\n React.useEffect(() => {\n return () => {\n cleanupBodyStyles();\n };\n }, []);\n\n return <DialogPrimitive.Root data-slot=\"dialog\" open={open} onOpenChange={onOpenChange} {...props} />\n}\n\nfunction DialogTrigger({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {\n return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />\n}\n\nfunction DialogPortal({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Portal>) {\n return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />\n}\n\nfunction DialogClose({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Close>) {\n return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />\n}\n\nfunction DialogOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {\n return (\n <DialogPrimitive.Overlay\n data-slot=\"dialog-overlay\"\n className={cn(\n \"fixed inset-0 z-50 bg-black/50\",\n \"data-[state=open]:animate-in data-[state=closed]:animate-out\",\n \"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n \"data-[state=closed]:pointer-events-none\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DialogContent({\n className,\n children,\n showCloseButton = true,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Content> & {\n showCloseButton?: boolean\n}) {\n return (\n <DialogPortal data-slot=\"dialog-portal\">\n <DialogOverlay />\n <DialogPrimitive.Content\n data-slot=\"dialog-content\"\n aria-describedby={undefined}\n className={cn(\n \"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg\",\n className\n )}\n {...props}\n >\n {children}\n {showCloseButton && (\n <DialogPrimitive.Close\n data-slot=\"dialog-close\"\n className=\"ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\"\n >\n <XIcon />\n <span className=\"sr-only\">Close</span>\n </DialogPrimitive.Close>\n )}\n </DialogPrimitive.Content>\n </DialogPortal>\n )\n}\n\nfunction DialogHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dialog-header\"\n className={cn(\"flex flex-col gap-2 text-center sm:text-left\", className)}\n {...props}\n />\n )\n}\n\nfunction DialogFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dialog-footer\"\n className={cn(\n \"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DialogTitle({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Title>) {\n return (\n <DialogPrimitive.Title\n data-slot=\"dialog-title\"\n className={cn(\"text-lg leading-none font-semibold\", className)}\n {...props}\n />\n )\n}\n\nfunction DialogDescription({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Description>) {\n return (\n <DialogPrimitive.Description\n data-slot=\"dialog-description\"\n className={cn(\"text-muted-foreground text-sm\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as AlertDialogPrimitive from \"@radix-ui/react-alert-dialog\"\n\nimport { cn } from \"../../lib/utils\"\nimport { buttonVariants } from \"./button\"\n\n/**\n * Clean up body styles that Radix may leave behind.\n * This fixes an issue where pointer-events: none gets stuck on body.\n */\nfunction cleanupBodyStyles() {\n if (typeof document !== 'undefined' && document.body.style.pointerEvents === 'none') {\n document.body.style.pointerEvents = '';\n }\n}\n\nfunction AlertDialog({\n open,\n onOpenChange,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Root>) {\n // Track previous open state to detect close transition\n const prevOpenRef = React.useRef(open);\n\n React.useEffect(() => {\n // When transitioning from open to closed, ensure cleanup after animation\n if (prevOpenRef.current === true && open === false) {\n const timeout = setTimeout(cleanupBodyStyles, 250); // After close animation (200ms + buffer)\n return () => clearTimeout(timeout);\n }\n prevOpenRef.current = open;\n }, [open]);\n\n // Cleanup on unmount\n React.useEffect(() => {\n return () => {\n cleanupBodyStyles();\n };\n }, []);\n\n return <AlertDialogPrimitive.Root data-slot=\"alert-dialog\" open={open} onOpenChange={onOpenChange} {...props} />\n}\n\nfunction AlertDialogTrigger({\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Trigger>) {\n return (\n <AlertDialogPrimitive.Trigger data-slot=\"alert-dialog-trigger\" {...props} />\n )\n}\n\nfunction AlertDialogPortal({\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Portal>) {\n return (\n <AlertDialogPrimitive.Portal data-slot=\"alert-dialog-portal\" {...props} />\n )\n}\n\nfunction AlertDialogOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Overlay>) {\n return (\n <AlertDialogPrimitive.Overlay\n data-slot=\"alert-dialog-overlay\"\n className={cn(\n \"fixed inset-0 z-50 bg-black/50\",\n \"data-[state=open]:animate-in data-[state=closed]:animate-out\",\n \"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n \"data-[state=closed]:pointer-events-none\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction AlertDialogContent({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Content>) {\n return (\n <AlertDialogPortal>\n <AlertDialogOverlay />\n <AlertDialogPrimitive.Content\n data-slot=\"alert-dialog-content\"\n className={cn(\n \"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg\",\n className\n )}\n {...props}\n />\n </AlertDialogPortal>\n )\n}\n\nfunction AlertDialogHeader({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"alert-dialog-header\"\n className={cn(\"flex flex-col gap-2 text-center sm:text-left\", className)}\n {...props}\n />\n )\n}\n\nfunction AlertDialogFooter({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"alert-dialog-footer\"\n className={cn(\n \"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction AlertDialogTitle({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Title>) {\n return (\n <AlertDialogPrimitive.Title\n data-slot=\"alert-dialog-title\"\n className={cn(\"text-lg font-semibold\", className)}\n {...props}\n />\n )\n}\n\nfunction AlertDialogDescription({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Description>) {\n return (\n <AlertDialogPrimitive.Description\n data-slot=\"alert-dialog-description\"\n className={cn(\"text-muted-foreground text-sm\", className)}\n {...props}\n />\n )\n}\n\nfunction AlertDialogAction({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Action>) {\n return (\n <AlertDialogPrimitive.Action\n className={cn(buttonVariants(), className)}\n {...props}\n />\n )\n}\n\nfunction AlertDialogCancel({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Cancel>) {\n return (\n <AlertDialogPrimitive.Cancel\n className={cn(buttonVariants({ variant: \"outline\" }), className)}\n {...props}\n />\n )\n}\n\nexport {\n AlertDialog,\n AlertDialogPortal,\n AlertDialogOverlay,\n AlertDialogTrigger,\n AlertDialogContent,\n AlertDialogHeader,\n AlertDialogFooter,\n AlertDialogTitle,\n AlertDialogDescription,\n AlertDialogAction,\n AlertDialogCancel,\n}\n","import * as React from \"react\"\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\"\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from \"lucide-react\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction DropdownMenu({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {\n return <DropdownMenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />\n}\n\nfunction DropdownMenuPortal({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {\n return (\n <DropdownMenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />\n )\n}\n\nfunction DropdownMenuTrigger({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {\n return (\n <DropdownMenuPrimitive.Trigger\n data-slot=\"dropdown-menu-trigger\"\n {...props}\n />\n )\n}\n\nfunction DropdownMenuContent({\n className,\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {\n return (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n data-slot=\"dropdown-menu-content\"\n sideOffset={sideOffset}\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md\",\n className\n )}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n )\n}\n\nfunction DropdownMenuGroup({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {\n return (\n <DropdownMenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />\n )\n}\n\nfunction DropdownMenuItem({\n className,\n inset,\n variant = \"default\",\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean\n variant?: \"default\" | \"destructive\"\n}) {\n return (\n <DropdownMenuPrimitive.Item\n data-slot=\"dropdown-menu-item\"\n data-inset={inset}\n data-variant={variant}\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuCheckboxItem({\n className,\n children,\n checked,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {\n return (\n <DropdownMenuPrimitive.CheckboxItem\n data-slot=\"dropdown-menu-checkbox-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n checked={checked}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n )\n}\n\nfunction DropdownMenuRadioGroup({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {\n return (\n <DropdownMenuPrimitive.RadioGroup\n data-slot=\"dropdown-menu-radio-group\"\n {...props}\n />\n )\n}\n\nfunction DropdownMenuRadioItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {\n return (\n <DropdownMenuPrimitive.RadioItem\n data-slot=\"dropdown-menu-radio-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <CircleIcon className=\"size-2 fill-current\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n )\n}\n\nfunction DropdownMenuLabel({\n className,\n inset,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {\n inset?: boolean\n}) {\n return (\n <DropdownMenuPrimitive.Label\n data-slot=\"dropdown-menu-label\"\n data-inset={inset}\n className={cn(\n \"px-2 py-1.5 text-sm font-medium data-[inset]:pl-8\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n return (\n <DropdownMenuPrimitive.Separator\n data-slot=\"dropdown-menu-separator\"\n className={cn(\"bg-border -mx-1 my-1 h-px\", className)}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuShortcut({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"dropdown-menu-shortcut\"\n className={cn(\n \"text-muted-foreground ml-auto text-xs tracking-widest\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuSub({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {\n return <DropdownMenuPrimitive.Sub data-slot=\"dropdown-menu-sub\" {...props} />\n}\n\nfunction DropdownMenuSubTrigger({\n className,\n inset,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {\n inset?: boolean\n}) {\n return (\n <DropdownMenuPrimitive.SubTrigger\n data-slot=\"dropdown-menu-sub-trigger\"\n data-inset={inset}\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8\",\n className\n )}\n {...props}\n >\n {children}\n <ChevronRightIcon className=\"ml-auto size-4\" />\n </DropdownMenuPrimitive.SubTrigger>\n )\n}\n\nfunction DropdownMenuSubContent({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {\n return (\n <DropdownMenuPrimitive.SubContent\n data-slot=\"dropdown-menu-sub-content\"\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport {\n DropdownMenu,\n DropdownMenuPortal,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuLabel,\n DropdownMenuItem,\n DropdownMenuCheckboxItem,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubTrigger,\n DropdownMenuSubContent,\n}\n","import React from 'react';\nimport {\n SidebarMenu,\n SidebarMenuItem,\n SidebarMenuButton,\n useSidebar,\n} from '../ui/sidebar';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n DropdownMenuLabel,\n} from '../ui/dropdown-menu';\nimport { Avatar, AvatarFallback, AvatarImage } from '../ui/avatar';\nimport {\n User,\n Settings,\n LogOut,\n ChevronsUpDown,\n Moon,\n Sun,\n Palette,\n} from 'lucide-react';\n\nexport interface UserMenuConfig {\n labels?: {\n profile?: string;\n settings?: string;\n theme?: string;\n lightMode?: string;\n darkMode?: string;\n systemTheme?: string;\n logout?: string;\n guest?: string;\n };\n}\n\nexport interface UserMenuUser {\n id: string;\n name?: string;\n email?: string;\n avatar?: string;\n}\n\nexport interface UserMenuCallbacks {\n onViewProfile?: () => void;\n onOpenSettings?: () => void;\n onThemeChange?: (theme: 'light' | 'dark' | 'system') => void;\n onLogout?: () => void;\n}\n\nexport interface UserMenuProps {\n user?: UserMenuUser | null;\n config?: UserMenuConfig;\n callbacks?: UserMenuCallbacks;\n currentTheme?: 'light' | 'dark' | 'system';\n /** Show theme options in the menu */\n showThemeOptions?: boolean;\n /** Additional menu items to render */\n additionalItems?: React.ReactNode;\n}\n\n// Get initials from name or email\nconst getInitials = (name?: string, email?: string): string => {\n if (name) {\n return name\n .split(' ')\n .map((n) => n[0])\n .slice(0, 2)\n .join('')\n .toUpperCase();\n }\n if (email) {\n return email[0].toUpperCase();\n }\n return 'U';\n};\n\n// Get display name\nconst getDisplayName = (user?: UserMenuUser | null, guestLabel?: string): string => {\n if (!user) return guestLabel || 'Guest';\n return user.name || user.email?.split('@')[0] || guestLabel || 'Guest';\n};\n\nexport const UserMenu: React.FC<UserMenuProps> = ({\n user,\n config,\n callbacks,\n currentTheme = 'system',\n showThemeOptions = true,\n additionalItems,\n}) => {\n const { isMobile } = useSidebar();\n\n const labels = {\n profile: config?.labels?.profile || 'Profile',\n settings: config?.labels?.settings || 'Settings',\n theme: config?.labels?.theme || 'Theme',\n lightMode: config?.labels?.lightMode || 'Light',\n darkMode: config?.labels?.darkMode || 'Dark',\n systemTheme: config?.labels?.systemTheme || 'System',\n logout: config?.labels?.logout || 'Log out',\n guest: config?.labels?.guest || 'Guest',\n };\n\n const displayName = getDisplayName(user, labels.guest);\n const initials = getInitials(user?.name, user?.email);\n\n return (\n <SidebarMenu>\n <SidebarMenuItem>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <SidebarMenuButton\n size=\"lg\"\n className=\"data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground\"\n tooltip={displayName}\n >\n <Avatar className=\"h-8 w-8 rounded-lg\">\n {user?.avatar && <AvatarImage src={user.avatar} alt={displayName} />}\n <AvatarFallback className=\"rounded-lg bg-primary/10 text-primary text-xs font-medium\">\n {initials}\n </AvatarFallback>\n </Avatar>\n <div className=\"grid flex-1 text-left text-sm leading-tight group-data-[collapsible=icon]:hidden\">\n <span className=\"truncate font-medium\">{displayName}</span>\n {user?.email && (\n <span className=\"truncate text-xs text-muted-foreground\">\n {user.email}\n </span>\n )}\n </div>\n <ChevronsUpDown className=\"ml-auto size-4 group-data-[collapsible=icon]:hidden\" />\n </SidebarMenuButton>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n className=\"w-[--radix-dropdown-menu-trigger-width] min-w-56 rounded-lg\"\n side={isMobile ? 'bottom' : 'right'}\n align=\"end\"\n sideOffset={4}\n >\n <DropdownMenuLabel className=\"p-0 font-normal\">\n <div className=\"flex items-center gap-2 px-1 py-1.5 text-left text-sm\">\n <Avatar className=\"h-8 w-8 rounded-lg\">\n {user?.avatar && <AvatarImage src={user.avatar} alt={displayName} />}\n <AvatarFallback className=\"rounded-lg bg-primary/10 text-primary text-xs font-medium\">\n {initials}\n </AvatarFallback>\n </Avatar>\n <div className=\"grid flex-1 text-left text-sm leading-tight\">\n <span className=\"truncate font-medium\">{displayName}</span>\n {user?.email && (\n <span className=\"truncate text-xs text-muted-foreground\">\n {user.email}\n </span>\n )}\n </div>\n </div>\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n \n {/* Profile */}\n {callbacks?.onViewProfile && (\n <DropdownMenuItem onClick={callbacks.onViewProfile}>\n <User className=\"mr-2 h-4 w-4\" />\n <span>{labels.profile}</span>\n </DropdownMenuItem>\n )}\n\n {/* Settings */}\n {callbacks?.onOpenSettings && (\n <DropdownMenuItem onClick={callbacks.onOpenSettings}>\n <Settings className=\"mr-2 h-4 w-4\" />\n <span>{labels.settings}</span>\n </DropdownMenuItem>\n )}\n\n {/* Additional items */}\n {additionalItems}\n\n {/* Theme options */}\n {showThemeOptions && callbacks?.onThemeChange && (\n <>\n <DropdownMenuSeparator />\n <DropdownMenuItem \n onClick={() => callbacks.onThemeChange?.('light')}\n className={currentTheme === 'light' ? 'bg-accent' : ''}\n >\n <Sun className=\"mr-2 h-4 w-4\" />\n <span>{labels.lightMode}</span>\n </DropdownMenuItem>\n <DropdownMenuItem \n onClick={() => callbacks.onThemeChange?.('dark')}\n className={currentTheme === 'dark' ? 'bg-accent' : ''}\n >\n <Moon className=\"mr-2 h-4 w-4\" />\n <span>{labels.darkMode}</span>\n </DropdownMenuItem>\n <DropdownMenuItem \n onClick={() => callbacks.onThemeChange?.('system')}\n className={currentTheme === 'system' ? 'bg-accent' : ''}\n >\n <Palette className=\"mr-2 h-4 w-4\" />\n <span>{labels.systemTheme}</span>\n </DropdownMenuItem>\n </>\n )}\n\n {/* Logout */}\n {callbacks?.onLogout && (\n <>\n <DropdownMenuSeparator />\n <DropdownMenuItem \n onClick={callbacks.onLogout}\n className=\"text-destructive focus:text-destructive focus:bg-destructive/10\"\n >\n <LogOut className=\"mr-2 h-4 w-4\" />\n <span>{labels.logout}</span>\n </DropdownMenuItem>\n </>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n </SidebarMenu>\n );\n};\n\nexport default UserMenu;\n","import React from 'react';\nimport { Card, CardHeader } from '../ui/card';\nimport { Button } from '../ui/button';\nimport { Avatar, AvatarFallback, AvatarImage } from '../ui/avatar';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '../ui/tooltip';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '../ui/dropdown-menu';\nimport {\n Bot,\n MoreVertical,\n Download,\n Upload,\n Trash2,\n Plus,\n Menu,\n Moon,\n Sun,\n ChevronDown,\n Check,\n} from 'lucide-react';\nimport { ReactNode } from 'react';\nimport { SidebarTrigger } from '../ui/sidebar';\nimport type { AgentOption } from '../../types/chatTypes';\nimport { ParticipantsSelector } from './AgentSelectors';\n\nexport interface ChatHeaderConfig {\n branding?: {\n logo?: ReactNode;\n title?: string;\n subtitle?: string;\n };\n agentSelector?: {\n enabled?: boolean;\n label?: string;\n hideIfSingle?: boolean;\n };\n labels?: {\n newThread?: string;\n exportData?: string;\n importData?: string;\n clearAll?: string;\n sidebarToggle?: string;\n customComponentToggle?: string;\n settings?: string;\n toggleDarkMode?: string;\n lightMode?: string;\n darkMode?: string;\n };\n customComponent?: {\n label?: string;\n icon?: ReactNode;\n onClick?: () => void;\n };\n /** Additional actions to render in the header (before the settings menu) */\n headerActions?: ReactNode;\n}\n\nexport interface ChatHeaderProps {\n config: ChatHeaderConfig;\n currentThreadTitle?: string | null;\n onSidebarToggle?: () => void;\n onCustomComponentToggle?: () => void;\n onNewThread?: () => void;\n onExportData?: () => void;\n onImportData?: (file: File) => void;\n onClearAll?: () => void;\n showCustomComponentButton?: boolean;\n isMobile?: boolean;\n showAgentSelector?: boolean;\n isMultiAgentMode?: boolean;\n agentOptions?: AgentOption[];\n selectedAgentId?: string | null;\n onSelectAgent?: (agentId: string) => void;\n participantIds?: string[];\n onParticipantsChange?: (ids: string[]) => void;\n className?: string;\n}\n\nexport const ChatHeader: React.FC<ChatHeaderProps> = ({\n config,\n currentThreadTitle,\n onSidebarToggle: _onSidebarToggle,\n onCustomComponentToggle,\n onNewThread,\n onExportData,\n onImportData,\n onClearAll,\n showCustomComponentButton,\n isMobile,\n showAgentSelector = false,\n isMultiAgentMode = false,\n agentOptions = [],\n selectedAgentId = null,\n onSelectAgent,\n participantIds,\n onParticipantsChange,\n className = '',\n}) => {\n const [isDarkMode, setIsDarkMode] = React.useState(() => {\n if (typeof window === 'undefined') return false;\n return document.documentElement.classList.contains('dark');\n });\n\n React.useEffect(() => {\n const observer = new MutationObserver(() => {\n setIsDarkMode(document.documentElement.classList.contains('dark'));\n });\n\n observer.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['class'],\n });\n\n // Listen for system theme changes\n const mediaQuery = globalThis.matchMedia('(prefers-color-scheme: dark)');\n const handleSystemThemeChange = (e: MediaQueryListEvent) => {\n const savedTheme = localStorage.getItem('theme');\n if (!savedTheme) {\n // Only update if user hasn't set an explicit preference\n setIsDarkMode(e.matches);\n }\n };\n\n mediaQuery.addEventListener('change', handleSystemThemeChange);\n\n return () => {\n observer.disconnect();\n mediaQuery.removeEventListener('change', handleSystemThemeChange);\n };\n }, []);\n\n const toggleDarkMode = () => {\n const isDark = document.documentElement.classList.contains('dark');\n if (isDark) {\n document.documentElement.classList.remove('dark');\n localStorage.setItem('theme', 'light');\n } else {\n document.documentElement.classList.add('dark');\n localStorage.setItem('theme', 'dark');\n }\n setIsDarkMode(!isDark);\n };\n\n\n const handleImportClick = () => {\n const input = document.createElement('input');\n input.type = 'file';\n input.accept = '.json';\n input.onchange = (e) => {\n const file = (e.target as HTMLInputElement).files?.[0];\n if (file && onImportData) {\n onImportData(file);\n }\n };\n input.click();\n };\n\n const selectedAgent = agentOptions.find((agent) => agent.id === selectedAgentId) || null;\n const agentPlaceholder = config.agentSelector?.label || 'Select agent';\n\n return (\n <Card\n data-chat-header\n className={`py-0 border-b rounded-none relative z-10 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/80 ${className}`}\n style={isMobile ? { paddingTop: 'env(safe-area-inset-top)' } : undefined}\n >\n <CardHeader className=\"p-2\">\n <div className=\"flex items-center justify-between gap-2\">\n {/* Left side - Sidebar toggle + Agent Selector */}\n <div className=\"flex items-center gap-1\">\n <Tooltip>\n <TooltipTrigger asChild>\n <SidebarTrigger className=\"-ml-1\" />\n </TooltipTrigger>\n <TooltipContent>\n {config.labels?.sidebarToggle || 'Toggle Sidebar'}\n </TooltipContent>\n </Tooltip>\n\n {/* Agent Selector */}\n {showAgentSelector && isMultiAgentMode && onParticipantsChange && (\n <ParticipantsSelector\n agents={agentOptions}\n participantIds={participantIds ?? agentOptions.map(a => a.id)}\n onParticipantsChange={onParticipantsChange}\n />\n )}\n {showAgentSelector && !isMultiAgentMode && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n className=\"h-9 px-3 gap-1.5 font-medium text-base hover:bg-accent/50\"\n >\n {selectedAgent?.avatarUrl ? (\n <Avatar className=\"h-5 w-5\">\n <AvatarImage src={selectedAgent.avatarUrl} alt={selectedAgent.name} />\n <AvatarFallback className=\"text-[10px]\">\n {selectedAgent.name.charAt(0).toUpperCase()}\n </AvatarFallback>\n </Avatar>\n ) : null}\n <span className=\"max-w-[200px] truncate\">\n {selectedAgent?.name || agentPlaceholder}\n </span>\n <ChevronDown className=\"h-4 w-4 opacity-50\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"w-[280px]\">\n {agentOptions.map((agent) => {\n const isSelected = agent.id === selectedAgentId;\n return (\n <DropdownMenuItem\n key={agent.id}\n onClick={() => onSelectAgent?.(agent.id)}\n className=\"flex items-start gap-3 p-3 cursor-pointer\"\n >\n {agent.avatarUrl ? (\n <Avatar className=\"h-6 w-6 mt-0.5 shrink-0\">\n <AvatarImage src={agent.avatarUrl} alt={agent.name} />\n <AvatarFallback className=\"text-[10px]\">\n {agent.name.charAt(0).toUpperCase()}\n </AvatarFallback>\n </Avatar>\n ) : (\n <div className=\"h-6 w-6 mt-0.5 shrink-0 flex items-center justify-center rounded-full bg-primary/10\">\n <Bot className=\"h-3.5 w-3.5 text-primary\" />\n </div>\n )}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium text-sm\">{agent.name}</span>\n {isSelected && (\n <Check className=\"h-4 w-4 text-primary shrink-0\" />\n )}\n </div>\n {agent.description && (\n <p className=\"text-xs text-muted-foreground mt-0.5 line-clamp-2\">\n {agent.description}\n </p>\n )}\n </div>\n </DropdownMenuItem>\n );\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n\n {/* Mobile title when no agent selector */}\n {!showAgentSelector && isMobile && (\n <span className=\"text-sm font-medium truncate max-w-[150px] ml-2\">\n {currentThreadTitle || config.branding?.title || 'Chat'}\n </span>\n )}\n </div>\n\n {/* Spacer */}\n <div className=\"flex-1\" />\n\n {/* Right side - Custom component button + Settings menu */}\n <div className=\"flex items-center gap-1\">\n {/* Custom component toggle button (desktop + mobile) */}\n {showCustomComponentButton && config.customComponent && (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={onCustomComponentToggle}\n >\n {config.customComponent.icon || <Menu className=\"h-4 w-4\" />}\n </Button>\n </TooltipTrigger>\n <TooltipContent>\n {config.customComponent.label || config.labels?.customComponentToggle || 'Toggle'}\n </TooltipContent>\n </Tooltip>\n )}\n\n {/* Custom header actions (passed from parent) */}\n {config.headerActions}\n\n {/* Settings dropdown menu */}\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"ghost\" size=\"icon\" className=\"h-8 w-8\">\n <MoreVertical className=\"h-4 w-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {onNewThread && (\n <>\n <DropdownMenuItem onClick={() => onNewThread?.()} className=\"font-medium text-primary\">\n <Plus className=\"h-4 w-4 mr-2\" />\n {config.labels?.newThread || 'New Thread'}\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n </>\n )}\n\n {onExportData && (\n <DropdownMenuItem onClick={onExportData}>\n <Download className=\"h-4 w-4 mr-2\" />\n {config.labels?.exportData || 'Export Data'}\n </DropdownMenuItem>\n )}\n\n {onImportData && (\n <DropdownMenuItem onClick={handleImportClick}>\n <Upload className=\"h-4 w-4 mr-2\" />\n {config.labels?.importData || 'Import Data'}\n </DropdownMenuItem>\n )}\n\n {(onExportData || onImportData) && (\n <DropdownMenuSeparator />\n )}\n\n <DropdownMenuItem onClick={toggleDarkMode}>\n {isDarkMode ? (\n <>\n <Sun className=\"h-4 w-4 mr-2\" />\n {config.labels?.lightMode || 'Light Mode'}\n </>\n ) : (\n <>\n <Moon className=\"h-4 w-4 mr-2\" />\n {config.labels?.darkMode || 'Dark Mode'}\n </>\n )}\n </DropdownMenuItem>\n\n {onClearAll && (\n <>\n <DropdownMenuSeparator />\n <DropdownMenuItem\n onClick={onClearAll}\n className=\"text-destructive\"\n >\n <Trash2 className=\"h-4 w-4 mr-2\" />\n {config.labels?.clearAll || 'Clear All'}\n </DropdownMenuItem>\n </>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n </div>\n </CardHeader>\n </Card>\n );\n};\n","import React, { memo, useMemo } from 'react';\nimport { Check, ChevronDown, Users, AtSign, X } from 'lucide-react';\nimport { AgentOption } from '../../types/chatTypes';\nimport { Button } from '../ui/button';\nimport { Avatar, AvatarFallback, AvatarImage } from '../ui/avatar';\nimport { Badge } from '../ui/badge';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n DropdownMenuSeparator,\n DropdownMenuLabel,\n} from '../ui/dropdown-menu';\nimport { getAgentColor, getAgentInitials, assignAgentColors } from '../../lib/chatUtils';\n\ninterface ParticipantsSelectorProps {\n /** All available agents */\n agents: AgentOption[];\n /** Currently selected participant IDs */\n participantIds: string[];\n /** Callback when participants change */\n onParticipantsChange: (ids: string[]) => void;\n /** Label for the selector */\n label?: string;\n /** Maximum participants to show in collapsed view */\n maxVisible?: number;\n /** Disabled state */\n disabled?: boolean;\n}\n\n/**\n * Multi-select dropdown for choosing which agents participate in the conversation.\n */\nexport const ParticipantsSelector: React.FC<ParticipantsSelectorProps> = memo(({\n agents,\n participantIds,\n onParticipantsChange,\n label = 'Team',\n maxVisible = 3,\n disabled = false,\n}) => {\n // Assign colors to agents that don't have them\n const agentsWithColors = useMemo(() => assignAgentColors(agents), [agents]);\n \n // Get selected agents\n const selectedAgents = useMemo(() => \n agentsWithColors.filter(a => participantIds.includes(a.id)),\n [agentsWithColors, participantIds]\n );\n \n const toggleParticipant = (agentId: string) => {\n if (participantIds.includes(agentId)) {\n // Don't allow removing the last participant\n if (participantIds.length > 1) {\n onParticipantsChange(participantIds.filter(id => id !== agentId));\n }\n } else {\n onParticipantsChange([...participantIds, agentId]);\n }\n };\n \n const selectAll = () => {\n onParticipantsChange(agentsWithColors.map(a => a.id));\n };\n \n const visibleAgents = selectedAgents.slice(0, maxVisible);\n const hiddenCount = selectedAgents.length - maxVisible;\n \n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n className=\"h-9 px-2 gap-1.5 text-sm hover:bg-accent/50\"\n disabled={disabled}\n >\n <Users className=\"h-4 w-4 text-muted-foreground\" />\n <div className=\"flex items-center gap-1\">\n {visibleAgents.length > 0 ? (\n <>\n <div className=\"flex -space-x-1.5\">\n {visibleAgents.map(agent => (\n <Avatar key={agent.id} className=\"h-5 w-5 border-2 border-background\">\n <AvatarImage src={agent.avatarUrl} alt={agent.name} />\n <AvatarFallback\n style={{ backgroundColor: agent.color || getAgentColor(agent.id), color: 'white' }}\n className=\"text-[8px]\"\n >\n {getAgentInitials(agent.name)}\n </AvatarFallback>\n </Avatar>\n ))}\n </div>\n {hiddenCount > 0 && (\n <span className=\"text-xs text-muted-foreground\">+{hiddenCount}</span>\n )}\n </>\n ) : (\n <span className=\"text-muted-foreground\">{label}</span>\n )}\n </div>\n <ChevronDown className=\"h-3 w-3 opacity-50\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"w-[260px]\">\n <DropdownMenuLabel className=\"flex items-center justify-between\">\n <span>Participants</span>\n {selectedAgents.length < agentsWithColors.length && (\n <Button variant=\"ghost\" size=\"sm\" className=\"h-6 text-xs\" onClick={selectAll}>\n Select All\n </Button>\n )}\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n {agentsWithColors.map(agent => {\n const isSelected = participantIds.includes(agent.id);\n const isLastSelected = isSelected && participantIds.length === 1;\n \n return (\n <DropdownMenuItem\n key={agent.id}\n onClick={() => toggleParticipant(agent.id)}\n className=\"flex items-center gap-3 p-2 cursor-pointer\"\n disabled={isLastSelected}\n >\n <Avatar className=\"h-6 w-6\">\n <AvatarImage src={agent.avatarUrl} alt={agent.name} />\n <AvatarFallback\n style={{ backgroundColor: agent.color || getAgentColor(agent.id), color: 'white' }}\n className=\"text-[10px]\"\n >\n {getAgentInitials(agent.name)}\n </AvatarFallback>\n </Avatar>\n <div className=\"flex-1 min-w-0\">\n <div className=\"font-medium text-sm truncate\">{agent.name}</div>\n {agent.description && (\n <div className=\"text-xs text-muted-foreground truncate\">{agent.description}</div>\n )}\n </div>\n {isSelected && (\n <Check className=\"h-4 w-4 text-primary shrink-0\" />\n )}\n </DropdownMenuItem>\n );\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n});\n\nParticipantsSelector.displayName = 'ParticipantsSelector';\n\ninterface TargetAgentSelectorProps {\n /** Available agents (should be filtered to participants only) */\n agents: AgentOption[];\n /** Currently targeted agent ID */\n targetAgentId: string | null;\n /** Callback when target changes */\n onTargetChange: (agentId: string | null) => void;\n /** Label for the selector */\n label?: string;\n /** Placeholder when no target is selected */\n placeholder?: string;\n /** Disabled state */\n disabled?: boolean;\n}\n\n/**\n * Single-select dropdown for choosing which agent to address with @mention.\n */\nexport const TargetAgentSelector: React.FC<TargetAgentSelectorProps> = memo(({\n agents,\n targetAgentId,\n onTargetChange,\n label = 'Target',\n placeholder = 'Select agent',\n disabled = false,\n}) => {\n // Assign colors to agents\n const agentsWithColors = useMemo(() => assignAgentColors(agents), [agents]);\n \n // Get selected agent\n const selectedAgent = useMemo(() => \n agentsWithColors.find(a => a.id === targetAgentId),\n [agentsWithColors, targetAgentId]\n );\n \n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n className=\"h-9 px-3 gap-1.5 font-medium text-base hover:bg-accent/50\"\n disabled={disabled}\n >\n <AtSign className=\"h-4 w-4 text-muted-foreground\" />\n {selectedAgent ? (\n <div className=\"flex items-center gap-2\">\n <Avatar className=\"h-5 w-5\">\n <AvatarImage src={selectedAgent.avatarUrl} alt={selectedAgent.name} />\n <AvatarFallback\n style={{ backgroundColor: selectedAgent.color || getAgentColor(selectedAgent.id), color: 'white' }}\n className=\"text-[10px]\"\n >\n {getAgentInitials(selectedAgent.name)}\n </AvatarFallback>\n </Avatar>\n <span className=\"max-w-[150px] truncate\">{selectedAgent.name}</span>\n </div>\n ) : (\n <span className=\"text-muted-foreground\">{placeholder}</span>\n )}\n <ChevronDown className=\"h-4 w-4 opacity-50\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"w-[280px]\">\n <DropdownMenuLabel>{label}</DropdownMenuLabel>\n <DropdownMenuSeparator />\n {agentsWithColors.map(agent => {\n const isSelected = agent.id === targetAgentId;\n \n return (\n <DropdownMenuItem\n key={agent.id}\n onClick={() => onTargetChange(agent.id)}\n className=\"flex items-start gap-3 p-3 cursor-pointer\"\n >\n <Avatar className=\"h-6 w-6 mt-0.5 shrink-0\">\n <AvatarImage src={agent.avatarUrl} alt={agent.name} />\n <AvatarFallback\n style={{ backgroundColor: agent.color || getAgentColor(agent.id), color: 'white' }}\n className=\"text-[10px]\"\n >\n {getAgentInitials(agent.name)}\n </AvatarFallback>\n </Avatar>\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium text-sm\">{agent.name}</span>\n {isSelected && (\n <Check className=\"h-4 w-4 text-primary shrink-0\" />\n )}\n </div>\n {agent.description && (\n <p className=\"text-xs text-muted-foreground mt-0.5 line-clamp-2\">\n {agent.description}\n </p>\n )}\n </div>\n </DropdownMenuItem>\n );\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n});\n\nTargetAgentSelector.displayName = 'TargetAgentSelector';\n\ninterface AgentBadgeProps {\n agent: AgentOption;\n onRemove?: () => void;\n showRemove?: boolean;\n size?: 'sm' | 'md';\n}\n\n/**\n * Badge displaying an agent with optional remove button.\n */\nexport const AgentBadge: React.FC<AgentBadgeProps> = memo(({\n agent,\n onRemove,\n showRemove = false,\n size = 'md',\n}) => {\n const color = agent.color || getAgentColor(agent.id);\n const avatarSize = size === 'sm' ? 'h-4 w-4' : 'h-5 w-5';\n const textSize = size === 'sm' ? 'text-xs' : 'text-sm';\n \n return (\n <Badge\n variant=\"secondary\"\n className=\"flex items-center gap-1.5 pr-1\"\n style={{ borderColor: color, borderWidth: 1 }}\n >\n <Avatar className={avatarSize}>\n <AvatarImage src={agent.avatarUrl} alt={agent.name} />\n <AvatarFallback\n style={{ backgroundColor: color, color: 'white' }}\n className=\"text-[8px]\"\n >\n {getAgentInitials(agent.name)}\n </AvatarFallback>\n </Avatar>\n <span className={textSize}>{agent.name}</span>\n {showRemove && onRemove && (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-4 w-4 ml-0.5 hover:bg-destructive/20\"\n onClick={(e) => {\n e.stopPropagation();\n onRemove();\n }}\n >\n <X className=\"h-3 w-3\" />\n </Button>\n )}\n </Badge>\n );\n});\n\nAgentBadge.displayName = 'AgentBadge';\n","import React, { useState, useRef, useCallback, useEffect, memo } from 'react';\nimport { useChatUserContext } from './UserContext';\nimport {\n AgentOption,\n MediaAttachment,\n FileUploadProgress,\n ChatConfig,\n VoiceComposerState,\n VoiceProvider,\n VoiceSegment,\n VoiceTranscript,\n} from '../../types/chatTypes';\nimport { createObjectUrlFromDataUrl } from '../../lib/utils';\nimport { appendVoiceSegments, mergeVoiceTranscripts, resolveVoiceProviderFactory } from '../../lib/voiceCompose';\nimport { Button } from '../ui/button';\nimport { Textarea } from '../ui/textarea';\nimport { Card, CardContent } from '../ui/card';\nimport { Badge } from '../ui/badge';\nimport { Progress } from '../ui/progress';\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../ui/tooltip';\nimport { VoiceComposer } from './VoiceComposer';\nimport {\n Send,\n Paperclip,\n Mic,\n Image,\n Video,\n FileText,\n X,\n Square,\n Play,\n Pause,\n Loader2,\n} from 'lucide-react';\n\ninterface ChatInputProps {\n value: string;\n onChange: (value: string) => void;\n onSubmit: (content: string, attachments: MediaAttachment[]) => void;\n attachments: MediaAttachment[];\n onAttachmentsChange: (attachments: MediaAttachment[]) => void;\n placeholder?: string;\n disabled?: boolean;\n isGenerating?: boolean;\n onStopGeneration?: () => void;\n enableFileUpload?: boolean;\n enableAudioRecording?: boolean;\n maxAttachments?: number;\n maxFileSize?: number;\n acceptedFileTypes?: string[];\n className?: string;\n config?: ChatConfig;\n mentionAgents?: AgentOption[];\n onTargetAgentChange?: (agentId: string | null) => void;\n}\n\ninterface MentionMatch {\n start: number;\n end: number;\n query: string;\n}\n\nfunction getActiveMentionMatch(value: string, caret: number): MentionMatch | null {\n const prefix = value.slice(0, caret);\n const match = /(^|\\s)@([\\w.-]*)$/.exec(prefix);\n if (!match) return null;\n\n const query = match[2] ?? '';\n return {\n start: prefix.length - query.length - 1,\n end: caret,\n query,\n };\n}\n\nfunction resolveTargetFromMentions(\n value: string,\n agents: AgentOption[],\n): AgentOption | null {\n const matches = value.matchAll(/(^|\\s)@([\\w.-]+)/g);\n\n for (const match of matches) {\n const mention = match[2]?.toLowerCase();\n if (!mention) continue;\n\n const agent = agents.find((candidate) =>\n candidate.id.toLowerCase() === mention ||\n candidate.name.toLowerCase() === mention\n );\n if (agent) return agent;\n }\n\n return null;\n}\n\n// File upload progress component - memoized\nconst FileUploadItem: React.FC<{\n file: { name: string; type?: string; size?: number };\n progress: number;\n onCancel: () => void;\n}> = memo(function FileUploadItem({ file, progress, onCancel }) {\n const guessTypeFromName = (name?: string): string => {\n const ext = (name || '').split('.').pop()?.toLowerCase();\n switch (ext) {\n case 'jpg':\n case 'jpeg':\n case 'png':\n case 'gif':\n case 'webp':\n case 'bmp':\n case 'svg':\n return 'image/*';\n case 'mp4':\n case 'mov':\n case 'm4v':\n case 'webm':\n return 'video/*';\n case 'mp3':\n case 'wav':\n case 'm4a':\n case 'ogg':\n return 'audio/*';\n default:\n return '';\n }\n };\n\n const getFileIcon = (type?: string, name?: string) => {\n const t = typeof type === 'string' && type.length > 0 ? type : guessTypeFromName(name);\n if (t.startsWith('image/')) return <Image className=\"h-4 w-4\" />;\n if (t.startsWith('video/')) return <Video className=\"h-4 w-4\" />;\n if (t.startsWith('audio/')) return <Mic className=\"h-4 w-4\" />;\n return <FileText className=\"h-4 w-4\" />;\n };\n\n const formatFileSize = (bytes: number) => {\n if (bytes === 0) return '0 Bytes';\n const k = 1024;\n const sizes = ['Bytes', 'KB', 'MB', 'GB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\n };\n\n return (\n <Card className=\"relative\">\n <CardContent className=\"p-3\">\n <div className=\"flex items-center gap-3\">\n {getFileIcon(file.type, file.name)}\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium truncate\">{file.name}</p>\n <p className=\"text-xs text-muted-foreground\">\n {formatFileSize(file.size ?? 0)}\n </p>\n <Progress value={progress} className=\"h-1 mt-1\" />\n </div>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-6 w-6\"\n onClick={onCancel}\n >\n <X className=\"h-3 w-3\" />\n </Button>\n </div>\n </CardContent>\n </Card>\n );\n});\n\n// Attachment preview component - memoized\nconst AttachmentPreview: React.FC<{\n attachment: MediaAttachment;\n onRemove: () => void;\n}> = memo(function AttachmentPreview({ attachment, onRemove }) {\n const [isPlaying, setIsPlaying] = useState(false);\n const [audioPlaybackSrc, setAudioPlaybackSrc] = useState(attachment.dataUrl);\n const audioRef = useRef<HTMLAudioElement>(null);\n\n useEffect(() => {\n if (attachment.kind !== 'audio' || !attachment.dataUrl.startsWith('data:')) {\n setAudioPlaybackSrc(attachment.dataUrl);\n return;\n }\n\n const objectUrl = createObjectUrlFromDataUrl(attachment.dataUrl);\n if (!objectUrl) {\n setAudioPlaybackSrc(attachment.dataUrl);\n return;\n }\n\n setAudioPlaybackSrc(objectUrl);\n\n return () => {\n URL.revokeObjectURL(objectUrl);\n };\n }, [attachment.kind, attachment.dataUrl]);\n\n const handlePlayPause = () => {\n if (audioRef.current) {\n if (isPlaying) {\n audioRef.current.pause();\n } else {\n audioRef.current.play();\n }\n setIsPlaying(!isPlaying);\n }\n };\n\n const formatDuration = (ms?: number) => {\n if (!ms) return '';\n const seconds = Math.floor(ms / 1000);\n const minutes = Math.floor(seconds / 60);\n return `${minutes}:${(seconds % 60).toString().padStart(2, '0')}`;\n };\n\n return (\n <Card className=\"relative group\">\n <CardContent className=\"p-2\">\n {attachment.kind === 'image' && (\n <div className=\"relative\">\n <img\n src={attachment.dataUrl}\n alt={attachment.fileName || 'Attachment'}\n className=\"w-full h-20 object-cover rounded\"\n />\n <div className=\"absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity rounded flex items-center justify-center\">\n <Button\n variant=\"destructive\"\n size=\"icon\"\n className=\"h-6 w-6\"\n onClick={onRemove}\n >\n <X className=\"h-3 w-3\" />\n </Button>\n </div>\n </div>\n )}\n\n {attachment.kind === 'video' && (\n <div className=\"relative\">\n <video\n src={attachment.dataUrl}\n poster={attachment.poster}\n className=\"w-full h-20 object-cover rounded\"\n muted\n />\n <div className=\"absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity rounded flex items-center justify-center\">\n <Button\n variant=\"destructive\"\n size=\"icon\"\n className=\"h-6 w-6\"\n onClick={onRemove}\n >\n <X className=\"h-3 w-3\" />\n </Button>\n </div>\n <Badge className=\"absolute bottom-1 right-1 text-xs\">\n {formatDuration(attachment.durationMs)}\n </Badge>\n </div>\n )}\n\n {attachment.kind === 'audio' && (\n <div className=\"flex items-center gap-2 p-2\">\n <Button\n variant=\"outline\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={handlePlayPause}\n >\n {isPlaying ? <Pause className=\"h-3 w-3\" /> : <Play className=\"h-3 w-3\" />}\n </Button>\n <div className=\"flex-1\">\n <p className=\"text-xs font-medium\">\n {attachment.fileName || 'Audio'}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {formatDuration(attachment.durationMs)}\n </p>\n </div>\n <audio\n ref={audioRef}\n onPlay={() => setIsPlaying(true)}\n onPause={() => setIsPlaying(false)}\n onEnded={() => setIsPlaying(false)}\n preload=\"metadata\"\n >\n <source src={audioPlaybackSrc} type={attachment.mimeType} />\n </audio>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity\"\n onClick={onRemove}\n >\n <X className=\"h-3 w-3\" />\n </Button>\n </div>\n )}\n\n {attachment.fileName && attachment.kind !== 'audio' && (\n <div className=\"absolute bottom-0 left-0 right-0 bg-black/70 text-white text-xs p-1 rounded-b\">\n <p className=\"truncate\">{attachment.fileName}</p>\n </div>\n )}\n </CardContent>\n </Card>\n );\n});\n\n// Audio recording component - memoized\nconst AudioRecorder: React.FC<{\n isRecording: boolean;\n onStartRecording: () => void;\n onStopRecording: () => void;\n onCancel: () => void;\n recordingDuration: number;\n config?: ChatConfig;\n}> = memo(function AudioRecorder({ isRecording, onStartRecording, onStopRecording, onCancel, recordingDuration, config }) {\n const formatTime = (seconds: number) => {\n const mins = Math.floor(seconds / 60);\n const secs = seconds % 60;\n return `${mins}:${secs.toString().padStart(2, '0')}`;\n };\n\n if (!isRecording) {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={onStartRecording}\n className=\"h-10 w-10\"\n >\n <Mic className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>{config?.labels?.recordAudioTooltip}</TooltipContent>\n </Tooltip>\n );\n }\n\n return (\n <Card className=\"border-red-200 bg-red-50 dark:border-red-800 dark:bg-red-950\">\n <CardContent className=\"p-3\">\n <div className=\"flex items-center gap-3\">\n <div className=\"flex items-center gap-2\">\n <div className=\"h-3 w-3 bg-red-500 rounded-full animate-pulse\" />\n <span className=\"text-sm font-medium text-red-700 dark:text-red-300\">\n {config?.labels?.voiceListening || 'Recording'}\n </span>\n </div>\n <Badge variant=\"outline\" className=\"text-xs\">\n {formatTime(recordingDuration)}\n </Badge>\n <div className=\"flex gap-1 ml-auto\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={onCancel}\n >\n <X className=\"h-3 w-3 mr-1\" />\n {config?.labels?.cancel || 'Cancel'}\n </Button>\n <Button\n variant=\"default\"\n size=\"sm\"\n onClick={onStopRecording}\n >\n <Square className=\"h-3 w-3 mr-1\" />\n {config?.labels?.voiceStop || 'Stop'}\n </Button>\n </div>\n </div>\n </CardContent>\n </Card>\n );\n});\n\nconst resolveVoiceErrorMessage = (error: unknown, config?: ChatConfig): string => {\n if (error instanceof DOMException && error.name === 'NotAllowedError') {\n return config?.labels?.voicePermissionDenied || 'Microphone access was denied.';\n }\n\n if (error instanceof Error && error.message.trim().length > 0) {\n return error.message;\n }\n\n return config?.labels?.voiceCaptureError || 'Unable to capture audio.';\n};\n\nconst clearVoiceTranscript = (): VoiceTranscript => ({});\nconst resolveVoiceSegmentDuration = (segment: VoiceSegment): number => segment.attachment.durationMs ?? 0;\n\nexport const ChatInput: React.FC<ChatInputProps> = memo(function ChatInput({\n value,\n onChange,\n onSubmit,\n attachments,\n onAttachmentsChange,\n placeholder = 'Type your message...',\n disabled = false,\n isGenerating = false,\n onStopGeneration,\n enableFileUpload = true,\n enableAudioRecording = true,\n maxAttachments = 4,\n maxFileSize = 10 * 1024 * 1024, // 10MB\n acceptedFileTypes = ['image/*', 'video/*', 'audio/*'],\n className = '',\n config,\n mentionAgents = [],\n onTargetAgentChange,\n}: ChatInputProps) {\n const voiceComposeEnabled = config?.voiceCompose?.enabled === true;\n const voiceDefaultMode = config?.voiceCompose?.defaultMode ?? 'text';\n const voiceReviewMode = config?.voiceCompose?.reviewMode ?? 'manual';\n const voiceAutoSendDelayMs = config?.voiceCompose?.autoSendDelayMs ?? 5000;\n const voicePersistComposer = config?.voiceCompose?.persistComposer ?? true;\n const voiceShowTranscriptPreview = config?.voiceCompose?.showTranscriptPreview ?? true;\n const voiceTranscriptMode = config?.voiceCompose?.transcriptMode ?? 'final-only';\n const voiceMaxRecordingMs = config?.voiceCompose?.maxRecordingMs;\n\n const [isRecording, setIsRecording] = useState(false);\n const { setContext } = useChatUserContext();\n const [recordingDuration, setRecordingDuration] = useState(0);\n const [uploadProgress, setUploadProgress] = useState<Map<string, FileUploadProgress>>(new Map());\n const [isVoiceComposerOpen, setIsVoiceComposerOpen] = useState(\n () => voiceComposeEnabled && voiceDefaultMode === 'voice',\n );\n const [voiceState, setVoiceState] = useState<VoiceComposerState>('idle');\n const [voiceDraft, setVoiceDraft] = useState<VoiceSegment | null>(null);\n const [voiceTranscript, setVoiceTranscript] = useState<VoiceTranscript>(clearVoiceTranscript);\n const [voiceDurationMs, setVoiceDurationMs] = useState(0);\n const [voiceAudioLevel, setVoiceAudioLevel] = useState(0);\n const [voiceCountdownMs, setVoiceCountdownMs] = useState(0);\n const [isVoiceAutoSendActive, setIsVoiceAutoSendActive] = useState(false);\n const [voiceError, setVoiceError] = useState<string | null>(null);\n const [activeMention, setActiveMention] = useState<MentionMatch | null>(null);\n const [activeMentionIndex, setActiveMentionIndex] = useState(0);\n\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const fileInputRef = useRef<HTMLInputElement>(null);\n const mediaRecorderRef = useRef<MediaRecorder | null>(null);\n const recordingStartTime = useRef<number>(0);\n const recordingInterval = useRef<ReturnType<typeof setInterval> | null>(null);\n const mediaStreamRef = useRef<MediaStream | null>(null);\n const voiceProviderRef = useRef<VoiceProvider | null>(null);\n const voiceDraftRef = useRef<VoiceSegment | null>(null);\n const voiceAppendBaseRef = useRef<VoiceSegment | null>(null);\n const voiceAppendBaseDurationRef = useRef(0);\n\n const filteredMentionAgents = React.useMemo(() => {\n if (!activeMention || mentionAgents.length === 0) return [];\n\n const query = activeMention.query.trim().toLowerCase();\n const rank = (agent: AgentOption) => {\n const id = agent.id.toLowerCase();\n const name = agent.name.toLowerCase();\n if (!query) return 0;\n if (name.startsWith(query) || id.startsWith(query)) return 0;\n if (name.includes(query) || id.includes(query)) return 1;\n return 2;\n };\n\n return mentionAgents\n .filter((agent) => rank(agent) < 2)\n .sort((left, right) => {\n const rankDiff = rank(left) - rank(right);\n if (rankDiff !== 0) return rankDiff;\n return left.name.localeCompare(right.name);\n })\n .slice(0, 6);\n }, [activeMention, mentionAgents]);\n\n const isMentionMenuOpen = filteredMentionAgents.length > 0;\n\n const syncMentionState = useCallback((nextValue: string, nextCaret?: number) => {\n const caret = typeof nextCaret === 'number'\n ? nextCaret\n : textareaRef.current?.selectionStart ?? nextValue.length;\n const nextMatch = getActiveMentionMatch(nextValue, caret);\n setActiveMention((prev) => {\n if (\n prev?.start === nextMatch?.start &&\n prev?.end === nextMatch?.end &&\n prev?.query === nextMatch?.query\n ) {\n return prev;\n }\n return nextMatch;\n });\n setActiveMentionIndex(0);\n }, []);\n\n // Cleanup recording on unmount\n useEffect(() => {\n return () => {\n if (mediaStreamRef.current) {\n mediaStreamRef.current.getTracks().forEach(track => track.stop());\n }\n if (recordingInterval.current) {\n clearInterval(recordingInterval.current);\n }\n if (voiceProviderRef.current) {\n void voiceProviderRef.current.destroy();\n voiceProviderRef.current = null;\n }\n };\n }, []);\n\n useEffect(() => {\n voiceDraftRef.current = voiceDraft;\n }, [voiceDraft]);\n\n useEffect(() => {\n if (!isMentionMenuOpen) {\n setActiveMentionIndex(0);\n return;\n }\n setActiveMentionIndex((prev) =>\n prev >= filteredMentionAgents.length ? 0 : prev,\n );\n }, [filteredMentionAgents.length, isMentionMenuOpen]);\n\n const selectMentionAgent = useCallback((agent: AgentOption) => {\n if (!activeMention) return;\n\n const replacement = `@${agent.name} `;\n const nextValue =\n value.slice(0, activeMention.start) +\n replacement +\n value.slice(activeMention.end);\n const nextCaret = activeMention.start + replacement.length;\n\n onChange(nextValue);\n onTargetAgentChange?.(agent.id);\n setActiveMention(null);\n setActiveMentionIndex(0);\n\n requestAnimationFrame(() => {\n textareaRef.current?.focus();\n textareaRef.current?.setSelectionRange(nextCaret, nextCaret);\n });\n }, [activeMention, onChange, onTargetAgentChange, value]);\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n if ((!value.trim() && attachments.length === 0) || disabled || isGenerating) return;\n\n const mentionedAgent = resolveTargetFromMentions(value, mentionAgents);\n if (mentionedAgent) {\n onTargetAgentChange?.(mentionedAgent.id);\n }\n\n onSubmit(value.trim(), attachments);\n onChange('');\n onAttachmentsChange([]);\n setActiveMention(null);\n setActiveMentionIndex(0);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (isMentionMenuOpen) {\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n setActiveMentionIndex((prev) =>\n prev >= filteredMentionAgents.length - 1 ? 0 : prev + 1,\n );\n return;\n }\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n setActiveMentionIndex((prev) =>\n prev <= 0 ? filteredMentionAgents.length - 1 : prev - 1,\n );\n return;\n }\n if ((e.key === 'Enter' || e.key === 'Tab') && filteredMentionAgents[activeMentionIndex]) {\n e.preventDefault();\n selectMentionAgent(filteredMentionAgents[activeMentionIndex]);\n return;\n }\n if (e.key === 'Escape') {\n e.preventDefault();\n setActiveMention(null);\n setActiveMentionIndex(0);\n return;\n }\n }\n\n if (e.key === 'Enter' && !e.shiftKey && !e.ctrlKey && window.innerWidth > 768) {\n e.preventDefault();\n handleSubmit(e as any);\n }\n };\n\n const processFile = async (file: File): Promise<MediaAttachment | null> => {\n if (file.size > maxFileSize) {\n alert(`File too large. Max allowed: ${Math.round(maxFileSize / 1024 / 1024)}MB`);\n return null;\n }\n\n const fileId = `${Date.now()}_${Math.random().toString(36).slice(2)}`;\n\n // Start upload progress\n setUploadProgress(prev => new Map(prev.set(fileId, {\n fileName: file.name,\n progress: 0,\n status: 'uploading',\n })));\n\n try {\n // Simulate upload progress\n for (let progress = 0; progress <= 100; progress += 20) {\n await new Promise(resolve => setTimeout(resolve, 100));\n setUploadProgress(prev => new Map(prev.set(fileId, {\n fileName: file.name,\n progress,\n status: 'uploading',\n })));\n }\n\n const dataUrl = await new Promise<string>((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result as string);\n reader.onerror = reject;\n reader.readAsDataURL(file);\n });\n\n setUploadProgress(prev => {\n const newMap = new Map(prev);\n newMap.delete(fileId);\n return newMap;\n });\n\n const attachment: MediaAttachment = {\n kind: file.type.startsWith('image/') ? 'image' :\n file.type.startsWith('video/') ? 'video' :\n file.type.startsWith('audio/') ? 'audio' : 'image',\n dataUrl,\n mimeType: file.type,\n fileName: file.name,\n size: file.size,\n };\n\n // For video files, try to get duration\n if (attachment.kind === 'video') {\n try {\n const video = document.createElement('video');\n video.src = dataUrl;\n await new Promise((resolve) => {\n video.onloadedmetadata = resolve;\n });\n attachment.durationMs = video.duration * 1000;\n } catch (error) {\n console.warn('Could not get video duration:', error);\n }\n }\n\n // If it's an image, mark as latest reference image in shared context\n if (attachment.kind === 'image') {\n setContext({ lastReferenceImage: { dataUrl: attachment.dataUrl, mimeType: attachment.mimeType, addedAt: Date.now() } });\n }\n return attachment;\n } catch (error) {\n console.error('Error processing file:', error);\n setUploadProgress(prev => {\n const newMap = new Map(prev);\n newMap.delete(fileId);\n return newMap;\n });\n alert('Failed to process file');\n return null;\n }\n };\n\n const handleFileSelect = async (e: React.ChangeEvent<HTMLInputElement>) => {\n const files = e.target.files;\n if (!files) return;\n\n const remainingSlots = maxAttachments - attachments.length;\n const filesToProcess = Array.from(files).slice(0, remainingSlots);\n\n for (const file of filesToProcess) {\n const attachment = await processFile(file);\n if (attachment) {\n onAttachmentsChange([...attachments, attachment]);\n }\n }\n\n // Reset input\n e.target.value = '';\n };\n\n const handleDrop = useCallback(async (e: React.DragEvent) => {\n e.preventDefault();\n if (!enableFileUpload) return;\n\n const files = Array.from(e.dataTransfer.files);\n const remainingSlots = maxAttachments - attachments.length;\n const filesToProcess = files.slice(0, remainingSlots);\n\n for (const file of filesToProcess) {\n const attachment = await processFile(file);\n if (attachment) {\n onAttachmentsChange([...attachments, attachment]);\n }\n }\n }, [attachments, enableFileUpload, maxAttachments, onAttachmentsChange]);\n\n const handleDragOver = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n }, []);\n\n const startRecording = async () => {\n try {\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n mediaStreamRef.current = stream;\n\n const mediaRecorder = new MediaRecorder(stream);\n mediaRecorderRef.current = mediaRecorder;\n\n const chunks: BlobPart[] = [];\n mediaRecorder.ondataavailable = (e) => {\n chunks.push(e.data);\n };\n\n mediaRecorder.onstop = async () => {\n const blob = new Blob(chunks, { type: 'audio/webm' });\n const dataUrl = await new Promise<string>((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result as string);\n reader.onerror = reject;\n reader.readAsDataURL(blob);\n });\n\n const attachment: MediaAttachment = {\n kind: 'audio',\n dataUrl,\n mimeType: blob.type,\n durationMs: recordingDuration * 1000,\n fileName: `audio_${new Date().toISOString().slice(0, 19)}.webm`,\n size: blob.size,\n };\n\n onAttachmentsChange([...attachments, attachment]);\n\n // Cleanup\n if (mediaStreamRef.current) {\n mediaStreamRef.current.getTracks().forEach(track => track.stop());\n mediaStreamRef.current = null;\n }\n };\n\n recordingStartTime.current = Date.now();\n setRecordingDuration(0);\n setIsRecording(true);\n mediaRecorder.start();\n\n recordingInterval.current = setInterval(() => {\n const duration = Math.floor((Date.now() - recordingStartTime.current) / 1000);\n setRecordingDuration(duration);\n }, 1000);\n\n } catch (error) {\n console.error('Error starting recording:', error);\n alert(config?.labels?.voicePermissionDenied || 'Microphone access was denied.');\n }\n };\n\n const stopRecording = () => {\n if (mediaRecorderRef.current && isRecording) {\n mediaRecorderRef.current.stop();\n setIsRecording(false);\n if (recordingInterval.current) {\n clearInterval(recordingInterval.current);\n }\n }\n };\n\n const cancelRecording = () => {\n if (mediaRecorderRef.current && isRecording) {\n mediaRecorderRef.current.stop();\n setIsRecording(false);\n if (recordingInterval.current) {\n clearInterval(recordingInterval.current);\n }\n // Don't process the recording\n if (mediaStreamRef.current) {\n mediaStreamRef.current.getTracks().forEach(track => track.stop());\n mediaStreamRef.current = null;\n }\n }\n };\n\n const resetVoiceComposerState = useCallback((nextState: VoiceComposerState = 'idle') => {\n setVoiceState(nextState);\n setVoiceDraft(null);\n voiceDraftRef.current = null;\n voiceAppendBaseRef.current = null;\n voiceAppendBaseDurationRef.current = 0;\n setVoiceTranscript(clearVoiceTranscript());\n setVoiceDurationMs(0);\n setVoiceAudioLevel(0);\n setVoiceCountdownMs(0);\n setIsVoiceAutoSendActive(false);\n setVoiceError(null);\n }, []);\n\n const armVoiceDraftForAppend = useCallback((segment: VoiceSegment | null) => {\n voiceAppendBaseRef.current = segment;\n voiceAppendBaseDurationRef.current = segment ? resolveVoiceSegmentDuration(segment) : 0;\n }, []);\n\n const handleVoiceProviderStateChange = useCallback((nextState: VoiceComposerState) => {\n if (\n voiceReviewMode === 'armed' &&\n (nextState === 'waiting_for_speech' || nextState === 'listening')\n ) {\n const currentDraft = voiceDraftRef.current;\n if (currentDraft) {\n armVoiceDraftForAppend(currentDraft);\n }\n }\n\n if (\n voiceReviewMode === 'armed' &&\n nextState === 'listening' &&\n voiceDraftRef.current\n ) {\n setVoiceCountdownMs(voiceAutoSendDelayMs);\n setIsVoiceAutoSendActive(false);\n }\n\n setVoiceState(nextState);\n }, [armVoiceDraftForAppend, voiceAutoSendDelayMs, voiceReviewMode]);\n\n const ensureVoiceProvider = useCallback(async () => {\n if (voiceProviderRef.current) {\n return voiceProviderRef.current;\n }\n\n const createProvider = resolveVoiceProviderFactory(config?.voiceCompose?.createProvider);\n const provider = await createProvider({\n onStateChange: handleVoiceProviderStateChange,\n onAudioLevelChange: setVoiceAudioLevel,\n onDurationChange: (durationMs) => {\n setVoiceDurationMs(voiceAppendBaseDurationRef.current + durationMs);\n },\n onTranscriptChange: (transcript) => {\n const baseTranscript = voiceAppendBaseRef.current?.transcript;\n setVoiceTranscript(\n baseTranscript\n ? mergeVoiceTranscripts(baseTranscript, transcript)\n : transcript,\n );\n },\n onSegmentReady: (segment) => {\n void (async () => {\n const previousSegment = voiceAppendBaseRef.current;\n\n try {\n const nextSegment = previousSegment\n ? await appendVoiceSegments(previousSegment, segment)\n : segment;\n\n voiceDraftRef.current = nextSegment;\n setVoiceDraft(nextSegment);\n setVoiceTranscript(nextSegment.transcript ?? clearVoiceTranscript());\n setVoiceDurationMs(resolveVoiceSegmentDuration(nextSegment));\n setVoiceAudioLevel(0);\n setVoiceCountdownMs(voiceAutoSendDelayMs);\n setIsVoiceAutoSendActive(voiceAutoSendDelayMs > 0);\n setVoiceError(null);\n if (voiceReviewMode === 'armed') {\n armVoiceDraftForAppend(nextSegment);\n } else {\n armVoiceDraftForAppend(null);\n }\n setVoiceState((currentState) =>\n voiceReviewMode === 'armed' && (\n currentState === 'waiting_for_speech' ||\n currentState === 'listening'\n )\n ? currentState\n : 'review');\n } catch (error) {\n const resolvedError = resolveVoiceErrorMessage(error, config);\n\n armVoiceDraftForAppend(null);\n setVoiceAudioLevel(0);\n setVoiceCountdownMs(0);\n setIsVoiceAutoSendActive(false);\n\n if (previousSegment) {\n voiceDraftRef.current = previousSegment;\n setVoiceDraft(previousSegment);\n setVoiceTranscript(previousSegment.transcript ?? clearVoiceTranscript());\n setVoiceDurationMs(resolveVoiceSegmentDuration(previousSegment));\n setVoiceError(resolvedError);\n setVoiceState('review');\n return;\n }\n\n voiceDraftRef.current = null;\n setVoiceDraft(null);\n setVoiceTranscript(clearVoiceTranscript());\n setVoiceDurationMs(0);\n setVoiceError(resolvedError);\n setVoiceState('error');\n }\n })();\n },\n onError: (error) => {\n const previousSegment = voiceAppendBaseRef.current;\n armVoiceDraftForAppend(null);\n setVoiceError(resolveVoiceErrorMessage(error, config));\n setVoiceAudioLevel(0);\n setVoiceCountdownMs(0);\n setIsVoiceAutoSendActive(false);\n\n if (previousSegment) {\n voiceDraftRef.current = previousSegment;\n setVoiceDraft(previousSegment);\n setVoiceTranscript(previousSegment.transcript ?? clearVoiceTranscript());\n setVoiceDurationMs(resolveVoiceSegmentDuration(previousSegment));\n setVoiceState('review');\n return;\n }\n\n voiceDraftRef.current = null;\n setVoiceDraft(null);\n setVoiceTranscript(clearVoiceTranscript());\n setVoiceDurationMs(0);\n setVoiceState('error');\n },\n }, {\n maxRecordingMs: voiceMaxRecordingMs,\n });\n\n voiceProviderRef.current = provider;\n return provider;\n }, [armVoiceDraftForAppend, config, handleVoiceProviderStateChange, voiceAutoSendDelayMs, voiceMaxRecordingMs, voiceReviewMode]);\n\n const closeVoiceComposer = useCallback(async () => {\n voiceAppendBaseRef.current = null;\n voiceAppendBaseDurationRef.current = 0;\n setIsVoiceComposerOpen(false);\n setVoiceError(null);\n setVoiceCountdownMs(0);\n setVoiceAudioLevel(0);\n setVoiceTranscript(clearVoiceTranscript());\n setVoiceDraft(null);\n voiceDraftRef.current = null;\n setVoiceDurationMs(0);\n setVoiceState('idle');\n\n if (voiceProviderRef.current) {\n await voiceProviderRef.current.cancel();\n }\n }, []);\n\n const startVoiceCapture = useCallback(async (appendToDraft = false) => {\n if (disabled || isGenerating) {\n return;\n }\n\n const previousDraft = appendToDraft ? voiceDraftRef.current : null;\n const previousDurationMs = previousDraft ? resolveVoiceSegmentDuration(previousDraft) : 0;\n\n setIsVoiceComposerOpen(true);\n setVoiceError(null);\n setVoiceCountdownMs(0);\n setVoiceAudioLevel(0);\n setIsVoiceAutoSendActive(false);\n voiceAppendBaseRef.current = previousDraft;\n voiceAppendBaseDurationRef.current = previousDurationMs;\n\n if (!previousDraft) {\n setVoiceDraft(null);\n voiceDraftRef.current = null;\n setVoiceTranscript(clearVoiceTranscript());\n setVoiceDurationMs(0);\n } else {\n setVoiceTranscript(previousDraft.transcript ?? clearVoiceTranscript());\n setVoiceDurationMs(previousDurationMs);\n }\n\n try {\n const provider = await ensureVoiceProvider();\n await provider.start();\n } catch (error) {\n const resolvedError = resolveVoiceErrorMessage(error, config);\n voiceAppendBaseRef.current = null;\n voiceAppendBaseDurationRef.current = 0;\n setVoiceAudioLevel(0);\n setVoiceCountdownMs(0);\n setIsVoiceAutoSendActive(false);\n\n if (previousDraft) {\n voiceDraftRef.current = previousDraft;\n setVoiceDraft(previousDraft);\n setVoiceTranscript(previousDraft.transcript ?? clearVoiceTranscript());\n setVoiceDurationMs(previousDurationMs);\n setVoiceError(resolvedError);\n setVoiceState('review');\n return;\n }\n\n voiceDraftRef.current = null;\n setVoiceDraft(null);\n setVoiceTranscript(clearVoiceTranscript());\n setVoiceDurationMs(0);\n setVoiceError(resolvedError);\n setVoiceState('error');\n }\n }, [disabled, isGenerating, ensureVoiceProvider, config]);\n\n const stopVoiceCapture = useCallback(async () => {\n if (!voiceProviderRef.current) return;\n\n try {\n await voiceProviderRef.current.stop();\n } catch (error) {\n setVoiceError(resolveVoiceErrorMessage(error, config));\n setVoiceState('error');\n }\n }, [config]);\n\n const cancelVoiceCapture = useCallback(async () => {\n voiceAppendBaseRef.current = null;\n voiceAppendBaseDurationRef.current = 0;\n if (voiceProviderRef.current) {\n await voiceProviderRef.current.cancel();\n }\n\n resetVoiceComposerState('idle');\n }, [resetVoiceComposerState]);\n\n const finalizeVoiceComposerAfterSend = useCallback(() => {\n if (voicePersistComposer) {\n resetVoiceComposerState('idle');\n setIsVoiceComposerOpen(true);\n return;\n }\n\n void closeVoiceComposer();\n }, [voicePersistComposer, resetVoiceComposerState, closeVoiceComposer]);\n\n const sendVoiceDraft = useCallback(() => {\n void (async () => {\n if (!voiceDraft || disabled || isGenerating) {\n return;\n }\n\n setVoiceState('sending');\n setVoiceCountdownMs(0);\n setIsVoiceAutoSendActive(false);\n\n if (voiceProviderRef.current) {\n await voiceProviderRef.current.cancel();\n }\n\n onSubmit('', [...attachments, voiceDraft.attachment]);\n onChange('');\n onAttachmentsChange([]);\n finalizeVoiceComposerAfterSend();\n })();\n }, [\n voiceDraft,\n disabled,\n isGenerating,\n onSubmit,\n attachments,\n onChange,\n onAttachmentsChange,\n finalizeVoiceComposerAfterSend,\n ]);\n\n const cancelVoiceAutoSend = useCallback(() => {\n void (async () => {\n if (voiceReviewMode === 'armed' && voiceProviderRef.current) {\n await voiceProviderRef.current.cancel();\n }\n\n armVoiceDraftForAppend(null);\n setVoiceAudioLevel(0);\n setVoiceState('review');\n })();\n\n setVoiceCountdownMs(0);\n setIsVoiceAutoSendActive(false);\n }, [armVoiceDraftForAppend, voiceReviewMode]);\n\n const pauseVoiceReview = useCallback(async () => {\n if (voiceState === 'listening') {\n await stopVoiceCapture();\n return;\n }\n\n if (voiceReviewMode === 'armed' && voiceProviderRef.current) {\n await voiceProviderRef.current.cancel();\n }\n\n armVoiceDraftForAppend(null);\n setVoiceAudioLevel(0);\n setVoiceState('review');\n }, [armVoiceDraftForAppend, stopVoiceCapture, voiceReviewMode, voiceState]);\n\n useEffect(() => {\n if (\n !voiceDraft ||\n voiceAutoSendDelayMs <= 0 ||\n !isVoiceAutoSendActive\n ) {\n return;\n }\n\n const canContinueCounting = voiceState === 'review' || (\n voiceReviewMode === 'armed' &&\n voiceState === 'waiting_for_speech'\n );\n\n if (!canContinueCounting) {\n return;\n }\n\n const timer = setInterval(() => {\n setVoiceCountdownMs((previous) => {\n const remaining = Math.max(0, previous - 100);\n\n if (remaining <= 0) {\n clearInterval(timer);\n queueMicrotask(() => {\n sendVoiceDraft();\n });\n }\n\n return remaining;\n });\n }, 100);\n\n return () => clearInterval(timer);\n }, [voiceState, voiceDraft, voiceReviewMode, voiceAutoSendDelayMs, isVoiceAutoSendActive, sendVoiceDraft]);\n\n const removeAttachment = (index: number) => {\n const newAttachments = attachments.filter((_, i) => i !== index);\n onAttachmentsChange(newAttachments);\n };\n\n const canAddMoreAttachments = attachments.length < maxAttachments;\n const showVoiceComposer = voiceComposeEnabled && isVoiceComposerOpen;\n\n return (\n <TooltipProvider>\n {/* <Card className={`border-t py-0 bg-transparent ${className}`}> */}\n {/* <CardContent className=\"p-4 pb-1 space-y-4 bg-transparent\"> */}\n {/* Upload progress */}\n <div className={`border-t py-0 bg-transparent ${className}`}>\n <div className=\"px-0 md:p-2 pb-1 space-y-4 bg-transparent\">\n {uploadProgress.size > 0 && (\n <div className=\"space-y-2\">\n {Array.from(uploadProgress.entries()).map(([id, progress]) => (\n <FileUploadItem\n key={id}\n file={{ name: progress.fileName } as File}\n progress={progress.progress}\n onCancel={() => {\n setUploadProgress(prev => {\n const newMap = new Map(prev);\n newMap.delete(id);\n return newMap;\n });\n }}\n />\n ))}\n </div>\n )}\n\n {/* Audio recording */}\n {isRecording && (\n <AudioRecorder\n isRecording={isRecording}\n onStartRecording={startRecording}\n onStopRecording={stopRecording}\n onCancel={cancelRecording}\n recordingDuration={recordingDuration}\n config={config}\n />\n )}\n\n {/* Attachments preview */}\n {attachments.length > 0 && (\n <div className=\"grid grid-cols-4 gap-2\">\n {attachments.map((attachment, index) => (\n <AttachmentPreview\n key={index}\n attachment={attachment}\n onRemove={() => removeAttachment(index)}\n />\n ))}\n </div>\n )}\n\n {/* Input area */}\n {showVoiceComposer ? (\n <div className=\"mb-1 flex justify-center\">\n <VoiceComposer\n state={voiceState}\n transcript={voiceTranscript}\n transcriptMode={voiceTranscriptMode}\n showTranscriptPreview={voiceShowTranscriptPreview}\n attachment={voiceDraft?.attachment ?? null}\n durationMs={voiceDurationMs}\n audioLevel={voiceAudioLevel}\n countdownMs={voiceCountdownMs}\n autoSendDelayMs={voiceAutoSendDelayMs}\n isAutoSendActive={isVoiceAutoSendActive}\n reviewMode={voiceReviewMode}\n errorMessage={voiceError}\n disabled={disabled || isGenerating}\n labels={config?.labels}\n onStart={() => {\n void startVoiceCapture();\n }}\n onStop={() => {\n void stopVoiceCapture();\n }}\n onPauseReview={() => {\n void pauseVoiceReview();\n }}\n onCancelAutoSend={() => {\n cancelVoiceAutoSend();\n }}\n onDiscard={() => {\n void cancelVoiceCapture();\n }}\n onRecordAgain={() => {\n void startVoiceCapture(true);\n }}\n onSendNow={sendVoiceDraft}\n onExit={() => {\n void closeVoiceComposer();\n }}\n />\n </div>\n ) : (\n <form onSubmit={handleSubmit} className=\"mb-1 flex justify-center\">\n <div\n className=\"flex items-end gap-2 p-3 border rounded-lg bg-background w-full md:min-w-3xl max-w-3xl\"\n onDrop={handleDrop}\n onDragOver={handleDragOver}\n >\n {/* File upload */}\n {enableFileUpload && canAddMoreAttachments && (\n <>\n <input\n ref={fileInputRef}\n type=\"file\"\n multiple\n accept={acceptedFileTypes.join(',')}\n onChange={handleFileSelect}\n className=\"hidden\"\n />\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n className=\"h-10 w-10\"\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n fileInputRef.current?.click();\n }}\n disabled={disabled}\n >\n <Paperclip className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>{config?.labels?.attachFileTooltip}</TooltipContent>\n </Tooltip>\n </>\n )}\n\n {/* Text input */}\n <div className=\"relative flex-1\">\n <Textarea\n ref={textareaRef}\n value={value}\n onChange={(e) => {\n onChange(e.target.value);\n syncMentionState(e.target.value, e.target.selectionStart ?? e.target.value.length);\n }}\n onSelect={(e) => {\n const target = e.target as HTMLTextAreaElement;\n syncMentionState(target.value, target.selectionStart ?? target.value.length);\n }}\n onClick={(e) => {\n const target = e.target as HTMLTextAreaElement;\n syncMentionState(target.value, target.selectionStart ?? target.value.length);\n }}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n disabled={disabled}\n className=\"max-h-[120px] resize-none border-0 bg-transparent focus-visible:ring-0 focus-visible:ring-offset-0\"\n rows={1}\n />\n {isMentionMenuOpen && (\n <div className=\"absolute bottom-full left-0 right-0 mb-2 overflow-hidden rounded-md border bg-popover shadow-md\">\n <div className=\"p-1\">\n {filteredMentionAgents.map((agent, index) => (\n <button\n key={agent.id}\n type=\"button\"\n className={`flex w-full items-center gap-2 rounded-sm px-3 py-2 text-left text-sm ${\n index === activeMentionIndex ? 'bg-accent text-accent-foreground' : 'hover:bg-accent/60'\n }`}\n onMouseDown={(mouseEvent) => {\n mouseEvent.preventDefault();\n selectMentionAgent(agent);\n }}\n >\n <span className=\"font-medium\">{agent.name}</span>\n {agent.description && (\n <span className=\"truncate text-xs text-muted-foreground\">\n {agent.description}\n </span>\n )}\n </button>\n ))}\n </div>\n </div>\n )}\n </div>\n\n {/* Audio recording / voice compose entry */}\n {enableAudioRecording && !isRecording && canAddMoreAttachments && !value.trim() && (\n voiceComposeEnabled ? (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n className=\"h-10 w-10\"\n onClick={() => {\n void startVoiceCapture();\n }}\n disabled={disabled || isGenerating}\n >\n <Mic className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>{config?.labels?.voiceEnter || config?.labels?.recordAudioTooltip}</TooltipContent>\n </Tooltip>\n ) : (\n <AudioRecorder\n isRecording={isRecording}\n onStartRecording={startRecording}\n onStopRecording={stopRecording}\n onCancel={cancelRecording}\n recordingDuration={recordingDuration}\n config={config}\n />\n )\n )}\n\n {/* Submit/Stop button */}\n {isGenerating ? (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n className=\"h-10 w-10\"\n onClick={onStopGeneration}\n >\n <Square className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>{config?.labels?.stopGenerationTooltip}</TooltipContent>\n </Tooltip>\n ) : (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n type=\"submit\"\n size=\"icon\"\n className=\"h-10 w-10\"\n disabled={disabled || (!value.trim() && attachments.length === 0)}\n >\n {disabled ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Send className=\"h-4 w-4\" />\n )}\n </Button>\n </TooltipTrigger>\n <TooltipContent>{config?.labels?.sendMessageTooltip}</TooltipContent>\n </Tooltip>\n )}\n </div>\n </form>\n )}\n\n {/* Help text */}\n <div className=\"text-[10px] text-muted-foreground text-center\">\n {window.innerWidth > 768 ? config?.labels?.inputHelpText : ''}\n\n {attachments.length > 0 && (\n <> • {attachments.length}/{maxAttachments} anexos</>\n )}\n {config?.labels?.footerLabel && (\n <> • {config.labels.footerLabel}</>\n )}\n </div>\n </div>\n </div>\n {/* </CardContent>\n </Card> */}\n </TooltipProvider >\n );\n});\n","import React, { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react';\nimport type { ChatUserContext } from '../../types/chatTypes';\n\ntype Setter = (next: Partial<ChatUserContext> | ((prev: ChatUserContext) => Partial<ChatUserContext>)) => void;\n\ninterface ChatUserContextValue {\n context: ChatUserContext;\n setContext: Setter;\n resetContext: () => void;\n}\n\nconst Ctx = createContext<ChatUserContextValue | undefined>(undefined);\n\nexport const ChatUserContextProvider: React.FC<{ children: React.ReactNode; initial?: Partial<ChatUserContext> }>\n = ({ children, initial }) => {\n const [ctx, setCtx] = useState<ChatUserContext>(() => ({\n updatedAt: Date.now(),\n ...(initial ?? {}),\n }));\n\n useEffect(() => {\n if (!initial) return;\n setCtx(prev => {\n const keys = Object.keys(initial) as (keyof typeof initial)[];\n const hasChanges = keys.some(k => prev[k] !== initial[k]);\n if (!hasChanges) return prev;\n return { ...prev, ...initial, updatedAt: Date.now() };\n });\n }, [initial]);\n\n const setPartial = useCallback<Setter>((next) => {\n setCtx(prev => {\n const partial = typeof next === 'function' ? next(prev) : next;\n return { ...prev, ...partial, updatedAt: Date.now() };\n });\n }, []);\n\n const value = useMemo<ChatUserContextValue>(() => ({\n context: ctx,\n setContext: setPartial,\n resetContext: () => setCtx({ updatedAt: Date.now() })\n }), [ctx, setPartial]);\n\n return <Ctx.Provider value={value}>{children}</Ctx.Provider>;\n};\n\nexport function useChatUserContext(): ChatUserContextValue {\n const v = useContext(Ctx);\n if (!v) throw new Error('useChatUserContext must be used within ChatUserContextProvider');\n return v;\n}\n","import type {\n AudioAttachment,\n CreateVoiceProvider,\n VoiceProvider,\n VoiceProviderHandlers,\n VoiceProviderOptions,\n VoiceSegment,\n VoiceTranscript,\n} from '../types/chatTypes';\n\nconst AUDIO_MIME_TYPES = [\n 'audio/webm;codecs=opus',\n 'audio/webm',\n 'audio/mp4',\n 'audio/ogg;codecs=opus',\n];\n\nconst pickRecorderMimeType = (): string | undefined => {\n if (typeof MediaRecorder === 'undefined') return undefined;\n\n for (const mimeType of AUDIO_MIME_TYPES) {\n if (typeof MediaRecorder.isTypeSupported === 'function' && MediaRecorder.isTypeSupported(mimeType)) {\n return mimeType;\n }\n }\n\n return undefined;\n};\n\nconst blobToDataUrl = (blob: Blob): Promise<string> =>\n new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result as string);\n reader.onerror = () => reject(reader.error ?? new Error('Failed to read recorded audio'));\n reader.readAsDataURL(blob);\n });\n\nconst joinTranscriptParts = (...parts: Array<string | undefined>): string | undefined => {\n const value = parts\n .map((part) => part?.trim())\n .filter((part): part is string => Boolean(part && part.length > 0))\n .join(' ')\n .trim();\n\n return value.length > 0 ? value : undefined;\n};\n\nconst getAudioContextCtor = (): typeof AudioContext | undefined =>\n globalThis.AudioContext ||\n (globalThis as typeof globalThis & { webkitAudioContext?: typeof AudioContext }).webkitAudioContext;\n\nconst getOfflineAudioContextCtor = (): typeof OfflineAudioContext | undefined =>\n globalThis.OfflineAudioContext ||\n (globalThis as typeof globalThis & { webkitOfflineAudioContext?: typeof OfflineAudioContext }).webkitOfflineAudioContext;\n\nconst attachmentToArrayBuffer = async (attachment: AudioAttachment): Promise<ArrayBuffer> => {\n const response = await fetch(attachment.dataUrl);\n return response.arrayBuffer();\n};\n\nconst decodeAudioAttachment = async (attachment: AudioAttachment): Promise<AudioBuffer> => {\n const AudioContextCtor = getAudioContextCtor();\n if (!AudioContextCtor) {\n throw new Error('Audio decoding is not supported in this browser');\n }\n\n const audioContext = new AudioContextCtor();\n\n try {\n const arrayBuffer = await attachmentToArrayBuffer(attachment);\n return await audioContext.decodeAudioData(arrayBuffer.slice(0));\n } finally {\n await closeAudioContext(audioContext);\n }\n};\n\nconst renderMergedBuffer = async (buffers: AudioBuffer[]): Promise<AudioBuffer> => {\n const OfflineAudioContextCtor = getOfflineAudioContextCtor();\n if (!OfflineAudioContextCtor) {\n throw new Error('Offline audio rendering is not supported in this browser');\n }\n\n const numberOfChannels = Math.max(...buffers.map((buffer) => buffer.numberOfChannels));\n const sampleRate = Math.max(...buffers.map((buffer) => buffer.sampleRate));\n const totalFrames = Math.max(1, Math.ceil(buffers.reduce((sum, buffer) => sum + (buffer.duration * sampleRate), 0)));\n const offlineContext = new OfflineAudioContextCtor(numberOfChannels, totalFrames, sampleRate);\n\n let offsetSeconds = 0;\n for (const buffer of buffers) {\n const source = offlineContext.createBufferSource();\n source.buffer = buffer;\n source.connect(offlineContext.destination);\n source.start(offsetSeconds);\n offsetSeconds += buffer.duration;\n }\n\n return offlineContext.startRendering();\n};\n\nconst encodeWav = (audioBuffer: AudioBuffer): Blob => {\n const numberOfChannels = audioBuffer.numberOfChannels;\n const sampleRate = audioBuffer.sampleRate;\n const bitsPerSample = 16;\n const bytesPerSample = bitsPerSample / 8;\n const dataLength = audioBuffer.length * numberOfChannels * bytesPerSample;\n const buffer = new ArrayBuffer(44 + dataLength);\n const view = new DataView(buffer);\n\n const writeString = (offset: number, value: string) => {\n for (let index = 0; index < value.length; index += 1) {\n view.setUint8(offset + index, value.charCodeAt(index));\n }\n };\n\n writeString(0, 'RIFF');\n view.setUint32(4, 36 + dataLength, true);\n writeString(8, 'WAVE');\n writeString(12, 'fmt ');\n view.setUint32(16, 16, true);\n view.setUint16(20, 1, true);\n view.setUint16(22, numberOfChannels, true);\n view.setUint32(24, sampleRate, true);\n view.setUint32(28, sampleRate * numberOfChannels * bytesPerSample, true);\n view.setUint16(32, numberOfChannels * bytesPerSample, true);\n view.setUint16(34, bitsPerSample, true);\n writeString(36, 'data');\n view.setUint32(40, dataLength, true);\n\n let offset = 44;\n const channelData = Array.from({ length: numberOfChannels }, (_, index) => audioBuffer.getChannelData(index));\n\n for (let sampleIndex = 0; sampleIndex < audioBuffer.length; sampleIndex += 1) {\n for (let channelIndex = 0; channelIndex < numberOfChannels; channelIndex += 1) {\n const sample = Math.max(-1, Math.min(1, channelData[channelIndex][sampleIndex]));\n const pcmValue = sample < 0 ? sample * 0x8000 : sample * 0x7fff;\n view.setInt16(offset, pcmValue, true);\n offset += 2;\n }\n }\n\n return new Blob([buffer], { type: 'audio/wav' });\n};\n\nconst resolveSegmentCount = (segment?: VoiceSegment | null): number => {\n const candidate = segment?.metadata?.segmentCount;\n return typeof candidate === 'number' && Number.isFinite(candidate) && candidate > 0 ? candidate : (segment ? 1 : 0);\n};\n\nexport const mergeVoiceTranscripts = (\n previous?: VoiceTranscript,\n incoming?: VoiceTranscript,\n): VoiceTranscript => ({\n final: joinTranscriptParts(previous?.final, incoming?.final),\n partial: joinTranscriptParts(previous?.final, incoming?.partial),\n});\n\nexport const appendVoiceSegments = async (\n previous: VoiceSegment,\n incoming: VoiceSegment,\n): Promise<VoiceSegment> => {\n const [previousBuffer, incomingBuffer] = await Promise.all([\n decodeAudioAttachment(previous.attachment),\n decodeAudioAttachment(incoming.attachment),\n ]);\n const mergedBuffer = await renderMergedBuffer([previousBuffer, incomingBuffer]);\n const mergedBlob = encodeWav(mergedBuffer);\n const dataUrl = await blobToDataUrl(mergedBlob);\n const segmentCount = resolveSegmentCount(previous) + resolveSegmentCount(incoming);\n\n return {\n attachment: {\n kind: 'audio',\n dataUrl,\n mimeType: mergedBlob.type,\n durationMs: Math.round(mergedBuffer.duration * 1000),\n fileName: `voice-${new Date().toISOString().replace(/[:.]/g, '-')}.wav`,\n size: mergedBlob.size,\n },\n transcript: mergeVoiceTranscripts(previous.transcript, incoming.transcript),\n metadata: {\n ...previous.metadata,\n ...incoming.metadata,\n segmentCount,\n source: segmentCount > 1 ? 'merged' : (incoming.metadata?.source ?? previous.metadata?.source),\n },\n };\n};\n\nconst stopStream = (stream: MediaStream | null) => {\n if (!stream) return;\n stream.getTracks().forEach((track) => track.stop());\n};\n\nconst closeAudioContext = async (audioContext: AudioContext | null) => {\n if (!audioContext) return;\n\n try {\n await audioContext.close();\n } catch {\n // Ignore close errors from partially-initialized contexts.\n }\n};\n\nconst emitDuration = (handlers: VoiceProviderHandlers, startedAt: number) => {\n handlers.onDurationChange?.(Math.max(0, Date.now() - startedAt));\n};\n\nexport const createManualVoiceProvider: CreateVoiceProvider = async (\n handlers,\n options = {},\n): Promise<VoiceProvider> => {\n let mediaRecorder: MediaRecorder | null = null;\n let mediaStream: MediaStream | null = null;\n let audioContext: AudioContext | null = null;\n let analyser: AnalyserNode | null = null;\n let levelData: Uint8Array | null = null;\n let levelFrame = 0;\n let durationTimer: ReturnType<typeof setInterval> | null = null;\n let maxDurationTimer: ReturnType<typeof setTimeout> | null = null;\n let startedAt = 0;\n let shouldEmitSegment = true;\n let isStarting = false;\n\n const clearTimers = () => {\n if (durationTimer) {\n clearInterval(durationTimer);\n durationTimer = null;\n }\n if (maxDurationTimer) {\n clearTimeout(maxDurationTimer);\n maxDurationTimer = null;\n }\n };\n\n const stopLevelLoop = () => {\n if (levelFrame) {\n cancelAnimationFrame(levelFrame);\n levelFrame = 0;\n }\n handlers.onAudioLevelChange?.(0);\n };\n\n const startLevelLoop = () => {\n if (!analyser || !levelData) return;\n\n const tick = () => {\n if (!analyser || !levelData) return;\n\n analyser.getByteTimeDomainData(levelData);\n let sum = 0;\n for (let index = 0; index < levelData.length; index += 1) {\n const centered = (levelData[index] - 128) / 128;\n sum += centered * centered;\n }\n\n const rms = Math.sqrt(sum / levelData.length);\n handlers.onAudioLevelChange?.(Math.min(1, rms * 4));\n levelFrame = requestAnimationFrame(tick);\n };\n\n tick();\n };\n\n const cleanupActiveResources = async () => {\n clearTimers();\n stopLevelLoop();\n stopStream(mediaStream);\n mediaStream = null;\n analyser = null;\n levelData = null;\n await closeAudioContext(audioContext);\n audioContext = null;\n };\n\n const finalizeStop = async () => {\n mediaRecorder = null;\n isStarting = false;\n await cleanupActiveResources();\n };\n\n const start = async () => {\n if (isStarting || mediaRecorder?.state === 'recording') {\n return;\n }\n\n if (!navigator.mediaDevices?.getUserMedia) {\n throw new Error('Audio capture is not supported in this browser');\n }\n\n if (typeof MediaRecorder === 'undefined') {\n throw new Error('MediaRecorder is not supported in this browser');\n }\n\n isStarting = true;\n shouldEmitSegment = true;\n handlers.onTranscriptChange?.({});\n handlers.onDurationChange?.(0);\n handlers.onAudioLevelChange?.(0);\n handlers.onStateChange?.('preparing');\n\n try {\n mediaStream = await navigator.mediaDevices.getUserMedia({ audio: true });\n const mimeType = pickRecorderMimeType();\n mediaRecorder = mimeType\n ? new MediaRecorder(mediaStream, { mimeType })\n : new MediaRecorder(mediaStream);\n\n const chunks: BlobPart[] = [];\n\n mediaRecorder.ondataavailable = (event) => {\n if (event.data.size > 0) {\n chunks.push(event.data);\n }\n };\n\n mediaRecorder.onerror = (event) => {\n const error = event.error ?? new Error('Audio recorder failed');\n handlers.onError?.(error);\n };\n\n mediaRecorder.onstop = async () => {\n const durationMs = startedAt > 0 ? Math.max(0, Date.now() - startedAt) : 0;\n\n try {\n if (shouldEmitSegment && chunks.length > 0) {\n const blob = new Blob(chunks, {\n type: mediaRecorder?.mimeType || mimeType || 'audio/webm',\n });\n const dataUrl = await blobToDataUrl(blob);\n\n handlers.onSegmentReady?.({\n attachment: {\n kind: 'audio',\n dataUrl,\n mimeType: blob.type || 'audio/webm',\n durationMs,\n fileName: `voice-${new Date().toISOString().replace(/[:.]/g, '-')}.webm`,\n size: blob.size,\n },\n metadata: { source: 'manual', segmentCount: 1 },\n });\n } else {\n handlers.onStateChange?.('idle');\n }\n } catch (error) {\n handlers.onError?.(error as Error);\n } finally {\n await finalizeStop();\n }\n };\n\n const AudioContextCtor = globalThis.AudioContext ||\n (globalThis as typeof globalThis & { webkitAudioContext?: typeof AudioContext }).webkitAudioContext;\n\n if (AudioContextCtor) {\n audioContext = new AudioContextCtor();\n await audioContext.resume().catch(() => undefined);\n const sourceNode = audioContext.createMediaStreamSource(mediaStream);\n analyser = audioContext.createAnalyser();\n analyser.fftSize = 1024;\n levelData = new Uint8Array(analyser.fftSize);\n sourceNode.connect(analyser);\n startLevelLoop();\n }\n\n startedAt = Date.now();\n emitDuration(handlers, startedAt);\n durationTimer = setInterval(() => emitDuration(handlers, startedAt), 200);\n if (options.maxRecordingMs && options.maxRecordingMs > 0) {\n maxDurationTimer = setTimeout(() => {\n void stop();\n }, options.maxRecordingMs);\n }\n\n mediaRecorder.start();\n handlers.onStateChange?.('listening');\n } catch (error) {\n isStarting = false;\n await cleanupActiveResources();\n throw error;\n }\n };\n\n const stop = async () => {\n if (!mediaRecorder || mediaRecorder.state === 'inactive') {\n return;\n }\n\n handlers.onStateChange?.('finishing');\n mediaRecorder.stop();\n };\n\n const cancel = async () => {\n shouldEmitSegment = false;\n\n if (mediaRecorder && mediaRecorder.state !== 'inactive') {\n mediaRecorder.stop();\n return;\n }\n\n await finalizeStop();\n handlers.onStateChange?.('idle');\n };\n\n const destroy = async () => {\n await cancel();\n };\n\n return {\n start,\n stop,\n cancel,\n destroy,\n };\n};\n\nexport const resolveVoiceProviderFactory = (\n createProvider?: CreateVoiceProvider,\n): CreateVoiceProvider => createProvider ?? createManualVoiceProvider;\n","import * as React from \"react\"\nimport * as ProgressPrimitive from \"@radix-ui/react-progress\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Progress({\n className,\n value,\n ...props\n}: React.ComponentProps<typeof ProgressPrimitive.Root>) {\n return (\n <ProgressPrimitive.Root\n data-slot=\"progress\"\n className={cn(\n \"bg-primary/20 relative h-2 w-full overflow-hidden rounded-full\",\n className\n )}\n {...props}\n >\n <ProgressPrimitive.Indicator\n data-slot=\"progress-indicator\"\n className=\"bg-primary h-full w-full flex-1 transition-all\"\n style={{ transform: `translateX(-${100 - (value || 0)}%)` }}\n />\n </ProgressPrimitive.Root>\n )\n}\n\nexport { Progress }\n","import React from 'react';\nimport type { AudioAttachment, ChatConfig, VoiceComposerState, VoiceReviewMode, VoiceTranscript, VoiceTranscriptMode } from '../../types/chatTypes';\nimport { Button } from '../ui/button';\nimport { Progress } from '../ui/progress';\nimport { Badge } from '../ui/badge';\nimport { Keyboard, Loader2, Mic, Send, Square, Trash2, X } from 'lucide-react';\n\ninterface VoiceComposerProps {\n state: VoiceComposerState;\n transcript?: VoiceTranscript;\n transcriptMode: VoiceTranscriptMode;\n showTranscriptPreview: boolean;\n attachment?: AudioAttachment | null;\n durationMs: number;\n audioLevel: number;\n countdownMs: number;\n autoSendDelayMs: number;\n isAutoSendActive: boolean;\n reviewMode: VoiceReviewMode;\n errorMessage?: string | null;\n disabled?: boolean;\n labels?: ChatConfig['labels'];\n onStart: () => void;\n onStop: () => void;\n onPauseReview: () => void;\n onCancelAutoSend: () => void;\n onDiscard: () => void;\n onRecordAgain: () => void;\n onSendNow: () => void;\n onExit: () => void;\n}\n\nconst formatDuration = (durationMs: number): string => {\n const totalSeconds = Math.max(0, Math.floor(durationMs / 1000));\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n return `${minutes}:${seconds.toString().padStart(2, '0')}`;\n};\n\nconst interpolateSeconds = (label: string | undefined, seconds: number): string => {\n if (!label) {\n return `Auto-sends in ${seconds}s`;\n }\n\n if (label.includes('{{seconds}}')) {\n return label.replace(/\\{\\{\\s*seconds\\s*\\}\\}/g, String(seconds));\n }\n\n return `${label} ${seconds}s`;\n};\n\nconst resolveStateLabel = (state: VoiceComposerState, labels?: ChatConfig['labels'], errorMessage?: string | null): string => {\n switch (state) {\n case 'preparing':\n return labels?.voicePreparing || 'Preparing microphone...';\n case 'waiting_for_speech':\n return labels?.voiceWaiting || 'Waiting for speech...';\n case 'listening':\n return labels?.voiceListening || 'Listening...';\n case 'finishing':\n return labels?.voiceFinishing || 'Finishing capture...';\n case 'review':\n return labels?.voiceReview || 'Ready to send';\n case 'sending':\n return labels?.voiceSending || 'Sending...';\n case 'error':\n return errorMessage || labels?.voiceCaptureError || 'Unable to capture audio.';\n case 'idle':\n default:\n return labels?.voiceIdle || 'Tap the mic to record';\n }\n};\n\nconst resolveTranscriptText = (\n transcript: VoiceTranscript | undefined,\n transcriptMode: VoiceTranscriptMode,\n): string | null => {\n if (transcriptMode === 'none' || !transcript) {\n return null;\n }\n\n if (transcriptMode === 'final-only') {\n return transcript.final?.trim() || null;\n }\n\n return transcript.final?.trim() || transcript.partial?.trim() || null;\n};\n\nexport const VoiceComposer: React.FC<VoiceComposerProps> = ({\n state,\n transcript,\n transcriptMode,\n showTranscriptPreview,\n attachment,\n durationMs,\n audioLevel,\n countdownMs,\n autoSendDelayMs,\n isAutoSendActive,\n reviewMode,\n errorMessage,\n disabled = false,\n labels,\n onStart,\n onStop,\n onPauseReview,\n onCancelAutoSend,\n onDiscard,\n onRecordAgain,\n onSendNow,\n onExit,\n}) => {\n const transcriptText = resolveTranscriptText(transcript, transcriptMode);\n const countdownSeconds = Math.max(1, Math.ceil(countdownMs / 1000));\n const isBusy = state === 'preparing' || state === 'finishing' || state === 'sending';\n const isCapturing = state === 'waiting_for_speech' || state === 'listening';\n const hasDraft = Boolean(attachment);\n const isDraftLayout = hasDraft;\n const isArmedDraft = isDraftLayout && reviewMode === 'armed' && (\n state === 'waiting_for_speech' || state === 'listening'\n );\n const draftStatusLabel = state === 'listening'\n ? (labels?.voiceListening || 'Listening...')\n : state === 'waiting_for_speech'\n ? (labels?.voiceWaiting || 'Waiting for speech...')\n : state === 'finishing'\n ? (labels?.voiceFinishing || 'Finishing capture...')\n : state === 'sending'\n ? (labels?.voiceSending || 'Sending...')\n : (labels?.voiceReview || 'Ready to send');\n const levelValue = isCapturing || state === 'preparing' || state === 'finishing'\n ? Math.max(8, Math.round(audioLevel * 100))\n : 0;\n const headerLabel = hasDraft && state !== 'sending' && state !== 'error'\n ? draftStatusLabel\n : state === 'error'\n ? (labels?.voiceCaptureError || 'Unable to capture audio.')\n : resolveStateLabel(state, labels, errorMessage);\n const reviewHelperText = isArmedDraft\n ? (labels?.voiceReviewArmedHint || 'Speak to add more before it sends.')\n : (labels?.voiceReviewPausedHint || labels?.voiceRecordAgain || 'Tap the mic to continue this message.');\n const orbIsListening = state === 'listening';\n const orbCanStop = !isDraftLayout && (state === 'waiting_for_speech' || state === 'listening');\n const orbIsReviewBusy = state === 'preparing' || state === 'finishing' || state === 'sending';\n const handleReviewOrbClick = () => {\n if (state === 'listening') {\n onStop();\n return;\n }\n\n if (isArmedDraft) {\n onPauseReview();\n return;\n }\n\n onRecordAgain();\n };\n\n return (\n <div className=\"w-full max-w-3xl rounded-2xl border bg-background p-3 shadow-sm sm:p-4 md:min-w-3xl\">\n <div className=\"flex items-center justify-between gap-2 sm:gap-3\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <Badge variant=\"outline\">{labels?.voiceTitle || 'Voice'}</Badge>\n <span className=\"truncate rounded-full bg-muted px-2.5 py-1 text-[11px] sm:text-xs text-muted-foreground\">\n {headerLabel}\n </span>\n </div>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"shrink-0 px-2 sm:px-3\"\n onClick={onExit}\n disabled={disabled || isBusy}\n >\n <Keyboard className=\"h-4 w-4\" />\n <span className=\"hidden sm:inline\">{labels?.voiceExit || 'Use keyboard'}</span>\n </Button>\n </div>\n\n {!isDraftLayout ? (\n <div className=\"mt-3 rounded-xl border border-dashed border-primary/30 bg-primary/5 px-3 py-3 text-center sm:px-4 sm:py-4\">\n <div className=\"mx-auto flex w-full max-w-sm flex-col items-center gap-3\">\n <Button\n type=\"button\"\n size=\"icon\"\n variant={isCapturing ? 'destructive' : 'outline'}\n className={`h-16 w-16 rounded-full sm:h-20 sm:w-20 ${isCapturing ? 'bg-red-500 hover:bg-red-600 text-white border-red-500' : 'border-red-200 bg-red-50 text-red-600 hover:bg-red-100 hover:text-red-700'}`}\n onClick={isCapturing ? onStop : onStart}\n disabled={disabled || isBusy}\n >\n {isBusy ? (\n <Loader2 className=\"h-7 w-7 animate-spin\" />\n ) : isCapturing ? (\n <Square className=\"h-7 w-7\" />\n ) : (\n <Mic className=\"h-7 w-7\" />\n )}\n </Button>\n\n <div className=\"w-full space-y-2\">\n <Progress value={levelValue} className=\"h-2\" />\n <div className=\"flex items-center justify-between text-xs text-muted-foreground\">\n <span>{formatDuration(durationMs)}</span>\n <span>{isCapturing ? (labels?.voiceStop || 'Stop recording') : (labels?.voiceStart || 'Start recording')}</span>\n </div>\n </div>\n\n {showTranscriptPreview && transcriptMode !== 'none' && transcriptText && (\n <div className=\"w-full rounded-lg border bg-background px-3 py-2 text-left text-sm\">\n {transcriptText}\n </div>\n )}\n </div>\n </div>\n ) : (\n <div className=\"mt-3 rounded-xl border bg-muted/20 p-3 sm:p-4\">\n <div className=\"flex items-center justify-between gap-2 text-xs text-muted-foreground\">\n <span>{formatDuration(durationMs)}</span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8 shrink-0 text-muted-foreground hover:text-destructive\"\n onClick={onDiscard}\n disabled={disabled}\n aria-label={labels?.voiceDiscard || 'Delete recording'}\n title={labels?.voiceDiscard || 'Delete recording'}\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </div>\n\n <div className=\"mt-4 flex flex-col items-center gap-4 text-center\">\n <Button\n type=\"button\"\n size=\"icon\"\n variant={orbCanStop ? 'destructive' : 'outline'}\n className={`h-20 w-20 rounded-full sm:h-24 sm:w-24 ${\n orbIsListening\n ? 'border-red-500 bg-red-500 text-white hover:bg-red-600'\n : isArmedDraft\n ? 'border-red-200 bg-red-50 text-red-600 shadow-[0_0_0_10px_rgba(239,68,68,0.08)] hover:bg-red-100 hover:text-red-700'\n : 'border-red-200 bg-red-50 text-red-600 hover:bg-red-100 hover:text-red-700'\n }`}\n onClick={handleReviewOrbClick}\n disabled={disabled || orbIsReviewBusy}\n >\n {orbIsReviewBusy ? (\n <Loader2 className=\"h-7 w-7 animate-spin\" />\n ) : orbIsListening ? (\n <Square className=\"h-7 w-7\" />\n ) : isArmedDraft ? (\n <Mic className=\"h-7 w-7 animate-pulse\" />\n ) : (\n <Mic className=\"h-7 w-7\" />\n )}\n </Button>\n\n <div className=\"max-w-sm space-y-1 px-2\">\n <p className=\"text-sm text-foreground\">{reviewHelperText}</p>\n {isCapturing && (\n <div className=\"mx-auto h-1.5 w-32 overflow-hidden rounded-full bg-red-100\">\n <div\n className=\"h-full rounded-full bg-red-500 transition-[width] duration-150\"\n style={{ width: `${levelValue}%` }}\n />\n </div>\n )}\n </div>\n </div>\n\n {attachment && (\n <div className=\"mt-4 rounded-lg border bg-background/90 p-2 shadow-sm\">\n <audio controls preload=\"metadata\" className=\"w-full\">\n <source src={attachment.dataUrl} type={attachment.mimeType} />\n </audio>\n </div>\n )}\n\n {showTranscriptPreview && transcriptMode !== 'none' && transcriptText && (\n <div className=\"mt-3 rounded-lg border bg-background px-3 py-2 text-left text-sm\">\n {transcriptText}\n </div>\n )}\n\n {isAutoSendActive && autoSendDelayMs > 0 && (\n <div className=\"mt-3 flex justify-center\">\n <div className=\"inline-flex items-center rounded-full border bg-background px-3 py-1 text-xs text-muted-foreground\">\n {interpolateSeconds(labels?.voiceAutoSendIn, countdownSeconds)}\n </div>\n </div>\n )}\n\n <div className=\"mt-4 grid grid-cols-1 gap-2 sm:flex sm:items-center sm:justify-end\">\n {isAutoSendActive && (\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" onClick={onCancelAutoSend} disabled={disabled} className=\"w-full sm:w-auto\">\n <X className=\"h-4 w-4\" />\n {labels?.voiceCancel || 'Cancel'}\n </Button>\n )}\n <Button type=\"button\" size=\"sm\" onClick={onSendNow} disabled={disabled} className=\"w-full sm:w-auto\">\n <Send className=\"h-4 w-4\" />\n {labels?.voiceSendNow || 'Send now'}\n </Button>\n </div>\n </div>\n )}\n\n {errorMessage && (\n <div className=\"mt-3 rounded-lg border border-destructive/30 bg-destructive/5 px-3 py-2 text-sm text-destructive\">\n {errorMessage}\n </div>\n )}\n </div>\n );\n};\n","import React, { useState } from 'react';\nimport { Sheet, SheetContent, SheetHeader, SheetTitle } from '../ui/sheet';\nimport { Avatar, AvatarFallback, AvatarImage } from '../ui/avatar';\nimport { ScrollArea } from '../ui/scroll-area';\nimport { Button } from '../ui/button';\nimport { Separator } from '../ui/separator';\nimport { Input } from '../ui/input';\nimport { Textarea } from '../ui/textarea';\nimport { cn } from '../../lib/utils';\nimport {\n User,\n Mail,\n AtSign,\n Calendar,\n MapPin,\n Phone,\n Globe,\n Building,\n Briefcase,\n Users,\n UserPlus,\n Image,\n BadgeCheck,\n FileText,\n Brain,\n Plus,\n Trash2,\n Target,\n Lightbulb,\n Info,\n Heart,\n Bot,\n Pencil,\n Check,\n X,\n} from 'lucide-react';\nimport type { MemoryItem } from '../../types/chatTypes';\n\nexport interface UserProfileConfig {\n labels?: {\n title?: string;\n basicInfo?: string;\n customFields?: string;\n memories?: string;\n addMemory?: string;\n noMemories?: string;\n close?: string;\n noCustomFields?: string;\n };\n}\n\nexport interface UserProfileUser {\n id: string;\n name?: string;\n email?: string;\n avatar?: string;\n}\n\n// Custom field definition - can be extended by login/external components\nexport interface CustomField {\n key: string;\n label: string;\n value: string | number | boolean | null | undefined;\n type?: 'text' | 'email' | 'phone' | 'url' | 'date' | 'number' | 'boolean';\n icon?: React.ReactNode;\n}\n\nexport interface UserProfileProps {\n isOpen: boolean;\n onClose: () => void;\n user?: UserProfileUser | null;\n /** Custom fields from userContext.customFields */\n customFields?: CustomField[] | Record<string, unknown>;\n /** User memories */\n memories?: MemoryItem[];\n config?: UserProfileConfig;\n /** Called when user wants to edit their profile */\n onEditProfile?: () => void;\n /** Called when user wants to logout */\n onLogout?: () => void;\n /** Called when user adds a memory */\n onAddMemory?: (content: string, category?: MemoryItem['category']) => void;\n /** Called when user updates a memory */\n onUpdateMemory?: (memoryId: string, content: string) => void;\n /** Called when user deletes a memory */\n onDeleteMemory?: (memoryId: string) => void;\n className?: string;\n}\n\n// Get initials from name or email\nconst getInitials = (name?: string, email?: string): string => {\n if (name) {\n return name\n .split(' ')\n .map((n) => n[0])\n .slice(0, 2)\n .join('')\n .toUpperCase();\n }\n if (email) {\n return email[0].toUpperCase();\n }\n return 'U';\n};\n\n// Map field types to icons\nconst getFieldIcon = (type?: string, key?: string): React.ReactNode => {\n const iconClass = 'h-4 w-4 text-muted-foreground';\n \n // Check by type first\n switch (type) {\n case 'email':\n return <Mail className={iconClass} />;\n case 'phone':\n return <Phone className={iconClass} />;\n case 'url':\n return <Globe className={iconClass} />;\n case 'date':\n return <Calendar className={iconClass} />;\n }\n \n // Check by common key names\n const lowerKey = key?.toLowerCase() || '';\n \n if (lowerKey.includes('follower')) return <Users className={iconClass} />;\n if (lowerKey.includes('following')) return <UserPlus className={iconClass} />;\n if (lowerKey.includes('post') || lowerKey.includes('publication')) return <Image className={iconClass} />;\n if (lowerKey.includes('verified') || lowerKey.includes('badge')) return <BadgeCheck className={iconClass} />;\n if (lowerKey.includes('bio')) return <FileText className={iconClass} />;\n \n // General fields\n if (lowerKey.includes('email')) return <Mail className={iconClass} />;\n if (lowerKey.includes('phone') || lowerKey.includes('tel')) return <Phone className={iconClass} />;\n if (lowerKey.includes('location') || lowerKey.includes('address') || lowerKey.includes('city')) return <MapPin className={iconClass} />;\n if (lowerKey.includes('company') || lowerKey.includes('org')) return <Building className={iconClass} />;\n if (lowerKey.includes('job') || lowerKey.includes('role') || lowerKey.includes('title') || lowerKey.includes('position')) return <Briefcase className={iconClass} />;\n if (lowerKey.includes('website') || lowerKey.includes('url') || lowerKey.includes('link')) return <Globe className={iconClass} />;\n if (lowerKey.includes('username') || lowerKey.includes('handle')) return <AtSign className={iconClass} />;\n if (lowerKey.includes('date') || lowerKey.includes('birthday') || lowerKey.includes('joined')) return <Calendar className={iconClass} />;\n \n return <User className={iconClass} />;\n};\n\n// Format value for display\nconst formatValue = (value: unknown, type?: string, key?: string): string => {\n if (value === null || value === undefined) return '-';\n if (typeof value === 'boolean') {\n if (key?.toLowerCase().includes('verified')) {\n return value ? 'Verified ✓' : 'Not verified';\n }\n return value ? 'Yes' : 'No';\n }\n if (type === 'date' && (typeof value === 'string' || typeof value === 'number')) {\n try {\n return new Date(value).toLocaleDateString('en-US');\n } catch {\n return String(value);\n }\n }\n return String(value);\n};\n\n// Convert Record<string, unknown> to CustomField[]\nconst normalizeCustomFields = (fields?: CustomField[] | Record<string, unknown>): CustomField[] => {\n if (!fields) return [];\n \n if (Array.isArray(fields)) {\n return fields;\n }\n \n // Convert object to array of fields\n return Object.entries(fields)\n .filter(([_, value]) => value !== null && value !== undefined && value !== '')\n .map(([key, value]) => ({\n key,\n label: key\n .replace(/([A-Z])/g, ' $1')\n .replace(/[_-]/g, ' ')\n .replace(/^\\w/, (c) => c.toUpperCase())\n .trim(),\n value: value as string | number | boolean,\n }));\n};\n\n// Get icon for memory category\nconst getMemoryCategoryIcon = (category?: MemoryItem['category']): React.ReactNode => {\n const iconClass = 'h-4 w-4 text-muted-foreground';\n switch (category) {\n case 'preference':\n return <Heart className={iconClass} />;\n case 'fact':\n return <Info className={iconClass} />;\n case 'goal':\n return <Target className={iconClass} />;\n case 'context':\n return <Lightbulb className={iconClass} />;\n default:\n return <Brain className={iconClass} />;\n }\n};\n\n// Get label for memory category\nconst getMemoryCategoryLabel = (category?: MemoryItem['category']): string => {\n switch (category) {\n case 'preference':\n return 'Preferência';\n case 'fact':\n return 'Fato';\n case 'goal':\n return 'Meta';\n case 'context':\n return 'Contexto';\n default:\n return 'Outro';\n }\n};\n\nexport const UserProfile: React.FC<UserProfileProps> = ({\n isOpen,\n onClose,\n user,\n customFields,\n memories = [],\n config,\n onEditProfile,\n onLogout,\n onAddMemory,\n onUpdateMemory,\n onDeleteMemory,\n className,\n}) => {\n const [newMemoryContent, setNewMemoryContent] = useState('');\n const [isAddingMemory, setIsAddingMemory] = useState(false);\n const [editingMemoryId, setEditingMemoryId] = useState<string | null>(null);\n const [editingMemoryContent, setEditingMemoryContent] = useState('');\n\n const handleAddMemory = () => {\n if (newMemoryContent.trim() && onAddMemory) {\n onAddMemory(newMemoryContent.trim(), 'other');\n setNewMemoryContent('');\n setIsAddingMemory(false);\n }\n };\n\n const handleStartEdit = (memory: MemoryItem) => {\n setEditingMemoryId(memory.id);\n setEditingMemoryContent(memory.content);\n };\n\n const handleSaveEdit = () => {\n if (editingMemoryId && editingMemoryContent.trim() && onUpdateMemory) {\n onUpdateMemory(editingMemoryId, editingMemoryContent.trim());\n setEditingMemoryId(null);\n setEditingMemoryContent('');\n }\n };\n\n const handleCancelEdit = () => {\n setEditingMemoryId(null);\n setEditingMemoryContent('');\n };\n\n const labels = {\n title: config?.labels?.title || 'Profile',\n basicInfo: config?.labels?.basicInfo || 'Account',\n customFields: config?.labels?.customFields || 'Details',\n memories: config?.labels?.memories || 'Memories',\n addMemory: config?.labels?.addMemory || 'Add memory',\n noMemories: config?.labels?.noMemories || 'No memories yet',\n close: config?.labels?.close || 'Close',\n noCustomFields: config?.labels?.noCustomFields || 'No additional information',\n };\n\n const displayName = user?.name || user?.email?.split('@')[0] || 'User';\n const initials = getInitials(user?.name, user?.email);\n const normalizedFields = normalizeCustomFields(customFields);\n\n return (\n <Sheet open={isOpen} onOpenChange={(open) => !open && onClose()}>\n <SheetContent\n side=\"right\"\n className={cn('w-full sm:max-w-md p-0 flex flex-col h-full overflow-hidden', className)}\n >\n <SheetHeader className=\"px-6 py-4 border-b shrink-0\">\n <div className=\"flex items-center justify-between\">\n <SheetTitle>{labels.title}</SheetTitle>\n </div>\n </SheetHeader>\n\n <ScrollArea className=\"flex-1 min-h-0\">\n <div className=\"p-6 space-y-6\">\n {/* User header */}\n <div className=\"flex flex-col items-center text-center space-y-4\">\n <Avatar className=\"h-24 w-24 shrink-0\">\n {user?.avatar && <AvatarImage src={user.avatar} alt={displayName} />}\n <AvatarFallback className=\"text-2xl bg-primary/10 text-primary\">\n {initials}\n </AvatarFallback>\n </Avatar>\n <div className=\"w-full px-2\">\n <h2 className=\"text-xl font-semibold break-words\">{displayName}</h2>\n {user?.email && (\n <p className=\"text-sm text-muted-foreground break-words\">{user.email}</p>\n )}\n </div>\n </div>\n\n <Separator />\n\n {/* Basic info */}\n <div className=\"space-y-3\">\n <h3 className=\"text-sm font-medium text-muted-foreground uppercase tracking-wider\">\n {labels.basicInfo}\n </h3>\n <div className=\"space-y-2\">\n <div className=\"flex items-start gap-3 p-3 rounded-lg bg-muted/50\">\n <User className=\"h-4 w-4 text-muted-foreground mt-0.5 shrink-0\" />\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-xs text-muted-foreground\">Name</p>\n <p className=\"text-sm font-medium break-words\">{displayName}</p>\n </div>\n </div>\n {user?.email && (\n <div className=\"flex items-start gap-3 p-3 rounded-lg bg-muted/50\">\n <AtSign className=\"h-4 w-4 text-muted-foreground mt-0.5 shrink-0\" />\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-xs text-muted-foreground\">Handle</p>\n <p className=\"text-sm font-medium break-words\">{user.email}</p>\n </div>\n </div>\n )}\n {user?.id && user.id !== user?.name && user.id !== user?.email && (\n <div className=\"flex items-start gap-3 p-3 rounded-lg bg-muted/50\">\n <User className=\"h-4 w-4 text-muted-foreground mt-0.5 shrink-0\" />\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-xs text-muted-foreground\">ID</p>\n <p className=\"text-sm font-medium break-words\">{user.id}</p>\n </div>\n </div>\n )}\n </div>\n </div>\n\n {/* Custom fields */}\n {normalizedFields.length > 0 && (\n <>\n <Separator />\n <div className=\"space-y-3\">\n <h3 className=\"text-sm font-medium text-muted-foreground uppercase tracking-wider\">\n {labels.customFields}\n </h3>\n <div className=\"space-y-2\">\n {normalizedFields.map((field) => {\n const isBioField = field.key.toLowerCase().includes('bio');\n return (\n <div\n key={field.key}\n className=\"flex items-start gap-3 p-3 rounded-lg bg-muted/50\"\n >\n <div className=\"mt-0.5 shrink-0\">\n {field.icon || getFieldIcon(field.type, field.key)}\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-xs text-muted-foreground\">{field.label}</p>\n <p className={cn(\n \"text-sm font-medium\",\n isBioField ? \"whitespace-pre-wrap break-words\" : \"break-words\"\n )}>\n {formatValue(field.value, field.type, field.key)}\n </p>\n </div>\n </div>\n );\n })}\n </div>\n </div>\n </>\n )}\n\n {/* Memories section */}\n <Separator />\n <div className=\"space-y-3\">\n <div className=\"flex items-center justify-between\">\n <h3 className=\"text-sm font-medium text-muted-foreground uppercase tracking-wider flex items-center gap-2\">\n <Brain className=\"h-4 w-4\" />\n {labels.memories}\n </h3>\n {onAddMemory && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-7 px-2\"\n onClick={() => setIsAddingMemory(true)}\n >\n <Plus className=\"h-4 w-4\" />\n </Button>\n )}\n </div>\n\n {/* Add memory input */}\n {isAddingMemory && onAddMemory && (\n <div className=\"flex gap-2\">\n <Input\n value={newMemoryContent}\n onChange={(e) => setNewMemoryContent(e.target.value)}\n placeholder=\"O que devo lembrar?\"\n className=\"flex-1 h-9\"\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleAddMemory();\n if (e.key === 'Escape') {\n setIsAddingMemory(false);\n setNewMemoryContent('');\n }\n }}\n autoFocus\n />\n <Button size=\"sm\" onClick={handleAddMemory} disabled={!newMemoryContent.trim()}>\n Salvar\n </Button>\n </div>\n )}\n\n {/* Memory list */}\n <div className=\"space-y-2\">\n {memories.length === 0 ? (\n <p className=\"text-sm text-muted-foreground text-center py-4\">\n {labels.noMemories}\n </p>\n ) : (\n memories.map((memory) => {\n const isEditing = editingMemoryId === memory.id;\n \n return (\n <div\n key={memory.id}\n className=\"flex items-start gap-3 p-3 rounded-lg bg-muted/50 group\"\n >\n <div className=\"mt-0.5 shrink-0\">\n {memory.source === 'agent' ? (\n <Bot className=\"h-4 w-4 text-primary\" />\n ) : (\n getMemoryCategoryIcon(memory.category)\n )}\n </div>\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2 mb-0.5\">\n <span className=\"text-xs text-muted-foreground\">\n {getMemoryCategoryLabel(memory.category)}\n </span>\n <span className=\"text-xs text-muted-foreground\">•</span>\n <span className=\"text-xs text-muted-foreground\">\n {memory.source === 'agent' ? 'IA' : 'Você'}\n </span>\n </div>\n {isEditing ? (\n <div className=\"space-y-2\">\n <Textarea\n value={editingMemoryContent}\n onChange={(e) => setEditingMemoryContent(e.target.value)}\n className=\"min-h-[60px] text-sm resize-none\"\n autoFocus\n onKeyDown={(e) => {\n if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) {\n handleSaveEdit();\n }\n if (e.key === 'Escape') {\n handleCancelEdit();\n }\n }}\n />\n <div className=\"flex gap-1 justify-end\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-7 px-2\"\n onClick={handleCancelEdit}\n >\n <X className=\"h-3.5 w-3.5 mr-1\" />\n Cancelar\n </Button>\n <Button\n size=\"sm\"\n className=\"h-7 px-2\"\n onClick={handleSaveEdit}\n disabled={!editingMemoryContent.trim()}\n >\n <Check className=\"h-3.5 w-3.5 mr-1\" />\n Salvar\n </Button>\n </div>\n </div>\n ) : (\n <p className=\"text-sm break-words\">{memory.content}</p>\n )}\n </div>\n {!isEditing && (onUpdateMemory || onDeleteMemory) && (\n <div className=\"flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity shrink-0\">\n {onUpdateMemory && (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-7 w-7\"\n onClick={() => handleStartEdit(memory)}\n >\n <Pencil className=\"h-3.5 w-3.5 text-muted-foreground\" />\n </Button>\n )}\n {onDeleteMemory && (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-7 w-7\"\n onClick={() => onDeleteMemory(memory.id)}\n >\n <Trash2 className=\"h-3.5 w-3.5 text-destructive\" />\n </Button>\n )}\n </div>\n )}\n </div>\n );\n })\n )}\n </div>\n </div>\n </div>\n </ScrollArea>\n\n {/* Footer actions */}\n <div className=\"p-4 border-t space-y-2 shrink-0\">\n {onEditProfile && (\n <Button\n variant=\"outline\"\n className=\"w-full\"\n onClick={onEditProfile}\n >\n Edit Profile\n </Button>\n )}\n {onLogout && (\n <Button\n variant=\"destructive\"\n className=\"w-full\"\n onClick={onLogout}\n >\n Log out\n </Button>\n )}\n </div>\n </SheetContent>\n </Sheet>\n );\n};\n\nexport default UserProfile;\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as ScrollAreaPrimitive from \"@radix-ui/react-scroll-area\"\n\nimport { cn } from \"../../lib/utils\"\n\nconst ScrollArea = React.forwardRef<\n HTMLDivElement,\n React.ComponentProps<typeof ScrollAreaPrimitive.Root> & {\n viewportClassName?: string\n }\n>(({ className, children, viewportClassName, onScroll, onScrollCapture, ...props }, ref) => {\n return (\n <ScrollAreaPrimitive.Root\n data-slot=\"scroll-area\"\n className={cn(\"relative\", className)}\n {...props}\n >\n <ScrollAreaPrimitive.Viewport\n ref={ref as React.Ref<HTMLDivElement>}\n data-slot=\"scroll-area-viewport\"\n className={cn(\n \"focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1\",\n viewportClassName\n )}\n onScroll={onScroll as any}\n onScrollCapture={onScrollCapture as any}\n >\n {children}\n </ScrollAreaPrimitive.Viewport>\n <ScrollBar />\n <ScrollAreaPrimitive.Corner />\n </ScrollAreaPrimitive.Root>\n )\n})\nScrollArea.displayName = \"ScrollArea\"\n\nfunction ScrollBar({\n className,\n orientation = \"vertical\",\n ...props\n}: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {\n return (\n <ScrollAreaPrimitive.ScrollAreaScrollbar\n data-slot=\"scroll-area-scrollbar\"\n orientation={orientation}\n className={cn(\n \"flex touch-none p-px transition-colors select-none\",\n orientation === \"vertical\" &&\n \"h-full w-2.5 border-l border-l-transparent\",\n orientation === \"horizontal\" &&\n \"h-2.5 flex-col border-t border-t-transparent\",\n className\n )}\n {...props}\n >\n <ScrollAreaPrimitive.ScrollAreaThumb\n data-slot=\"scroll-area-thumb\"\n className=\"bg-border relative flex-1 rounded-full\"\n />\n </ScrollAreaPrimitive.ScrollAreaScrollbar>\n )\n}\n\nexport { ScrollArea, ScrollBar }\n","import React, { useState, useRef, useEffect } from 'react';\nimport { ChatThread, ChatConfig } from '../../types/chatTypes';\nimport { formatDate } from '../../lib/utils';\nimport { Button } from '../ui/button';\nimport { Input } from '../ui/input';\nimport { Card, CardContent, CardHeader, CardTitle } from '../ui/card';\nimport { Badge } from '../ui/badge';\nimport { ScrollArea } from '../ui/scroll-area';\nimport { Separator } from '../ui/separator';\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from '../ui/dialog';\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from '../ui/alert-dialog';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '../ui/dropdown-menu';\nimport { TooltipProvider } from '../ui/tooltip';\nimport {\n Plus,\n MessageSquare,\n MoreVertical,\n Edit2,\n Trash2,\n Archive,\n Search,\n Filter,\n Calendar,\n Hash,\n X,\n Check,\n} from 'lucide-react';\n\ninterface ThreadManagerProps {\n threads: ChatThread[];\n currentThreadId?: string | null;\n config?: ChatConfig;\n onCreateThread?: (title?: string) => void;\n onSelectThread?: (threadId: string) => void;\n onRenameThread?: (threadId: string, newTitle: string) => void;\n onDeleteThread?: (threadId: string) => void;\n onArchiveThread?: (threadId: string) => void;\n isOpen?: boolean;\n onClose?: () => void;\n className?: string;\n}\n\n// Individual thread item component\nconst ThreadItem: React.FC<{\n thread: ChatThread;\n isActive: boolean;\n config?: ChatConfig;\n onSelect: () => void;\n onRename: (newTitle: string) => void;\n onDelete: () => void;\n onArchive: () => void;\n}> = ({ thread, isActive, config, onSelect, onRename, onDelete, onArchive }) => {\n const [isEditing, setIsEditing] = useState(false);\n const [editTitle, setEditTitle] = useState(thread.title);\n const inputRef = useRef<HTMLInputElement>(null);\n\n useEffect(() => {\n if (isEditing && inputRef.current) {\n inputRef.current.focus();\n inputRef.current.select();\n }\n }, [isEditing]);\n\n const handleSaveEdit = () => {\n const trimmedTitle = editTitle.trim();\n if (trimmedTitle && trimmedTitle !== thread.title) {\n onRename(trimmedTitle);\n }\n setIsEditing(false);\n };\n\n const handleCancelEdit = () => {\n setEditTitle(thread.title);\n setIsEditing(false);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter') {\n handleSaveEdit();\n } else if (e.key === 'Escape') {\n handleCancelEdit();\n }\n };\n\n return (\n <Card className={`cursor-pointer transition-all duration-200 hover:shadow-md py-0 ${\n isActive ? 'ring-2 ring-primary bg-primary/5' : 'hover:bg-muted/50'\n }`}>\n <CardContent className=\"p-3 max-w-sm\">\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"flex-1 min-w-0\" onClick={onSelect}>\n {isEditing ? (\n <div className=\"flex items-center gap-2\">\n <Input\n ref={inputRef}\n value={editTitle}\n onChange={(e) => setEditTitle(e.target.value)}\n onKeyDown={handleKeyDown}\n onBlur={handleSaveEdit}\n className=\"h-8 text-sm\"\n placeholder={config?.labels?.threadNamePlaceholder || \"Conversation name\"}\n />\n <Button size=\"sm\" variant=\"ghost\" onClick={handleSaveEdit}>\n <Check className=\"h-3 w-3\" />\n </Button>\n <Button size=\"sm\" variant=\"ghost\" onClick={handleCancelEdit}>\n <X className=\"h-3 w-3\" />\n </Button>\n </div>\n ) : (\n <>\n <h4 className=\"font-medium text-sm truncate mb-1\">\n {thread.title}\n </h4>\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <div className=\"flex items-center gap-1\">\n <Hash className=\"h-3 w-3\" />\n {thread.messageCount} msgs\n </div>\n <Separator orientation=\"vertical\" className=\"h-3\" />\n <div className=\"flex items-center gap-1\">\n <Calendar className=\"h-3 w-3\" />\n {formatDate(thread.updatedAt, config?.labels)}\n </div>\n {thread.isArchived && (\n <>\n <Separator orientation=\"vertical\" className=\"h-3\" />\n <Badge variant=\"secondary\" className=\"text-xs\">\n <Archive className=\"h-2 w-2 mr-1\" />\n {config?.labels?.archiveThread || 'Archived'}\n </Badge>\n </>\n )}\n </div>\n </>\n )}\n </div>\n\n {!isEditing && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"ghost\" size=\"icon\" className=\"h-6 w-6 m-auto\">\n <MoreVertical className=\"h-3 w-3\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onClick={() => setIsEditing(true)}>\n <Edit2 className=\"h-4 w-4 mr-2\" />\n {config?.labels?.renameThread || 'Rename'}\n </DropdownMenuItem>\n <DropdownMenuItem onClick={onArchive}>\n <Archive className=\"h-4 w-4 mr-2\" />\n {thread.isArchived \n ? (config?.labels?.unarchiveThread || 'Unarchive')\n : (config?.labels?.archiveThread || 'Archive')}\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem onClick={onDelete} className=\"text-destructive\">\n <Trash2 className=\"h-4 w-4 mr-2\" />\n {config?.labels?.deleteThread || 'Delete'}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n </div>\n </CardContent>\n </Card>\n );\n};\n\n// Create thread dialog\nconst CreateThreadDialog: React.FC<{\n onCreateThread: (title?: string) => void;\n config?: ChatConfig;\n}> = ({ onCreateThread, config }) => {\n const [title, setTitle] = useState('');\n const [isOpen, setIsOpen] = useState(false);\n\n const handleCreate = () => {\n onCreateThread(title.trim() || undefined);\n setTitle('');\n setIsOpen(false);\n };\n\n return (\n <Dialog open={isOpen} onOpenChange={setIsOpen}>\n <DialogTrigger asChild>\n <Button variant=\"outline\" className=\"w-full\">\n <Plus className=\"h-4 w-4 mr-2\" />\n {config?.labels?.createNewThread || 'New Conversation'}\n </Button>\n </DialogTrigger>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>{config?.labels?.createNewThread || 'Create New Conversation'}</DialogTitle>\n <DialogDescription>\n Give your new conversation a name or leave blank to auto-generate one.\n </DialogDescription>\n </DialogHeader>\n <Input\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n placeholder={config?.labels?.threadNamePlaceholder || \"Conversation name (optional)\"}\n onKeyDown={(e) => e.key === 'Enter' && handleCreate()}\n autoFocus\n />\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => setIsOpen(false)}>\n {config?.labels?.cancel || 'Cancel'}\n </Button>\n <Button onClick={handleCreate}>\n {config?.labels?.create || 'Create'}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n};\n\nexport const ThreadManager: React.FC<ThreadManagerProps> = ({\n threads,\n currentThreadId,\n config,\n onCreateThread,\n onSelectThread,\n onRenameThread,\n onDeleteThread,\n onArchiveThread,\n isOpen = false,\n onClose,\n className = '',\n}) => {\n const [searchQuery, setSearchQuery] = useState('');\n const [showArchived, setShowArchived] = useState(false);\n const [deleteThreadId, setDeleteThreadId] = useState<string | null>(null);\n\n // Filter threads based on search and archive filter\n const filteredThreads = threads.filter(thread => {\n const title = (thread.title ?? '').toString();\n const matchesSearch = title.toLowerCase().includes(searchQuery.toLowerCase());\n const matchesArchiveFilter = showArchived || !thread.isArchived;\n return matchesSearch && matchesArchiveFilter;\n });\n\n // Group threads by date\n const groupedThreads = filteredThreads.reduce((groups, thread) => {\n const date = new Date(thread.updatedAt);\n const today = new Date();\n const yesterday = new Date(today.getTime() - 24 * 60 * 60 * 1000);\n \n let groupKey: string;\n if (date.toDateString() === today.toDateString()) {\n groupKey = config?.labels?.today || 'Today';\n } else if (date.toDateString() === yesterday.toDateString()) {\n groupKey = config?.labels?.yesterday || 'Yesterday';\n } else {\n groupKey = date.toLocaleDateString('en-US', {\n weekday: 'long',\n day: '2-digit',\n month: 'long',\n });\n }\n\n if (!groups[groupKey]) {\n groups[groupKey] = [];\n }\n groups[groupKey].push(thread);\n return groups;\n }, {} as Record<string, ChatThread[]>);\n\n const handleDeleteThread = (threadId: string) => {\n onDeleteThread?.(threadId);\n setDeleteThreadId(null);\n };\n\n if (!isOpen) return null;\n\n return (\n <TooltipProvider>\n <div className={`fixed inset-0 z-50 bg-background/80 backdrop-blur-sm ${className}`}>\n <div className=\"fixed left-0 top-0 h-full w-full max-w-md border-r bg-background shadow-lg\">\n <Card className=\"h-full border-0 rounded-none\">\n <CardHeader className=\"border-b\">\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"flex items-center gap-2\">\n <MessageSquare className=\"h-5 w-5\" />\n {config?.labels?.newChat || 'Conversations'}\n </CardTitle>\n <Button variant=\"ghost\" size=\"icon\" onClick={onClose} >\n <X className=\"h-4 w-4\" />\n </Button>\n </div>\n \n {/* Search and filters */}\n <div className=\"space-y-3\">\n <div className=\"relative\">\n <Search className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground\" />\n <Input\n placeholder={config?.labels?.search || \"Search conversations...\"}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"pl-9\"\n />\n </div>\n \n <div className=\"flex items-center justify-between\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setShowArchived(!showArchived)}\n className=\"text-xs\"\n >\n <Filter className=\"h-3 w-3 mr-1\" />\n {showArchived \n ? (config?.labels?.hideArchived || 'Hide Archived')\n : (config?.labels?.showArchived || 'Show Archived')}\n </Button>\n \n <Badge variant=\"secondary\" className=\"text-xs\">\n {filteredThreads.length} / {threads.length}\n </Badge>\n </div>\n </div>\n </CardHeader>\n\n <CardContent className=\"p-0 flex-1\">\n <div className=\"p-4\">\n {onCreateThread && (\n <CreateThreadDialog onCreateThread={onCreateThread} config={config} />\n )}\n </div>\n\n <ScrollArea className=\"h-[calc(100vh-280px)]\">\n <div className=\"px-4 pb-4 space-y-4\">\n {Object.keys(groupedThreads).length === 0 ? (\n <div className=\"text-center py-8 text-muted-foreground\">\n <MessageSquare className=\"h-12 w-12 mx-auto mb-3 opacity-50\" />\n <p className=\"text-sm\">\n {searchQuery \n ? (config?.labels?.noThreadsFound || 'No conversations found')\n : (config?.labels?.noThreadsYet || 'No conversations yet')}\n </p>\n </div>\n ) : (\n Object.entries(groupedThreads).map(([group, groupThreads]: [string, ChatThread[]]) => (\n <div key={group}>\n <h3 className=\"text-sm font-medium text-muted-foreground mb-2 px-2\">\n {group}\n </h3>\n <div className=\"space-y-2\">\n {groupThreads.map((thread) => (\n <ThreadItem\n key={thread.id}\n thread={thread}\n isActive={currentThreadId === thread.id}\n config={config}\n onSelect={() => onSelectThread?.(thread.id)}\n onRename={(newTitle) => onRenameThread?.(thread.id, newTitle)}\n onDelete={() => setDeleteThreadId(thread.id)}\n onArchive={() => onArchiveThread?.(thread.id)}\n />\n ))}\n </div>\n </div>\n ))\n )}\n </div>\n </ScrollArea>\n </CardContent>\n </Card>\n </div>\n\n {/* Delete confirmation dialog - only render when needed to avoid Radix focus conflicts */}\n {deleteThreadId && (\n <AlertDialog open={!!deleteThreadId} onOpenChange={() => setDeleteThreadId(null)}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>{config?.labels?.deleteConfirmTitle || 'Delete Conversation'}</AlertDialogTitle>\n <AlertDialogDescription>\n {config?.labels?.deleteConfirmDescription || 'Are you sure you want to delete this conversation? This action cannot be undone.'}\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>{config?.labels?.cancel || 'Cancel'}</AlertDialogCancel>\n <AlertDialogAction\n onClick={() => deleteThreadId && handleDeleteThread(deleteThreadId)}\n className=\"bg-destructive text-destructive-foreground hover:bg-destructive/90\"\n >\n {config?.labels?.deleteThread || 'Delete'}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n )}\n </div>\n </TooltipProvider>\n );\n};\n"],"mappings":"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","names":["Sidebar","import_react","import_jsx_runtime","import_react_slot","import_class_variance_authority","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","ThinkingIndicator","ThinkingBlock","remarkGfm","rehypeHighlight","LongContentShell","PlainTextContent","React","StreamingText","ReactMarkdown","MediaRenderer","formatDuration","ToolCallsDisplay","import_react","import_jsx_runtime","React","import_react_slot","import_class_variance_authority","import_lucide_react","React","import_jsx_runtime","React","import_lucide_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","open","React","import_lucide_react","import_jsx_runtime","cleanupBodyStyles","React","import_jsx_runtime","cleanupBodyStyles","import_lucide_react","import_jsx_runtime","import_lucide_react","import_lucide_react","import_jsx_runtime","import_jsx_runtime","Sidebar","import_react","import_lucide_react","import_react","import_lucide_react","import_jsx_runtime","import_jsx_runtime","React","import_react","import_react","import_jsx_runtime","offset","import_jsx_runtime","import_lucide_react","import_jsx_runtime","import_lucide_react","import_jsx_runtime","FileUploadItem","AttachmentPreview","formatDuration","AudioRecorder","ChatInput","React","import_react","React","import_jsx_runtime","import_lucide_react","import_jsx_runtime","getInitials","import_lucide_react","import_jsx_runtime","Sidebar","import_react","import_lucide_react","import_jsx_runtime","CreateThreadDialog"]}
|