import { useState, useRef, useCallback } from 'react'; import { Import } from 'lucide-react'; import { useQueryClient } from '@tanstack/react-query'; import { QueryKeys, TStartupConfig } from 'librechat-data-provider'; import { Spinner, useToastContext, Label, Button } from '@librechat/client'; import { useUploadConversationsMutation } from '~/data-provider'; import { NotificationSeverity } from '~/common'; import { useLocalize } from '~/hooks'; import { cn, logger } from '~/utils'; function ImportConversations() { const localize = useLocalize(); const queryClient = useQueryClient(); const { showToast } = useToastContext(); const fileInputRef = useRef(null); const [isUploading, setIsUploading] = useState(false); const handleSuccess = useCallback(() => { showToast({ message: localize('com_ui_import_conversation_success'), status: NotificationSeverity.SUCCESS, }); setIsUploading(false); }, [localize, showToast]); const handleError = useCallback( (error: unknown) => { logger.error('Import error:', error); setIsUploading(false); const isUnsupportedType = error?.toString().includes('Unsupported import type'); showToast({ message: localize( isUnsupportedType ? 'com_ui_import_conversation_file_type_error' : 'com_ui_import_conversation_error', ), status: NotificationSeverity.ERROR, }); }, [localize, showToast], ); const uploadFile = useUploadConversationsMutation({ onSuccess: handleSuccess, onError: handleError, onMutate: () => setIsUploading(true), }); const handleFileUpload = useCallback( async (file: File) => { try { const startupConfig = queryClient.getQueryData([QueryKeys.startupConfig]); const maxFileSize = startupConfig?.conversationImportMaxFileSize; if (maxFileSize && file.size > maxFileSize) { const size = (maxFileSize / (1024 * 1024)).toFixed(2); showToast({ message: localize('com_error_files_upload_too_large', { 0: size }), status: NotificationSeverity.ERROR, }); setIsUploading(false); return; } const formData = new FormData(); formData.append('file', file, encodeURIComponent(file.name || 'File')); uploadFile.mutate(formData); } catch (error) { logger.error('File processing error:', error); setIsUploading(false); showToast({ message: localize('com_ui_import_conversation_upload_error'), status: NotificationSeverity.ERROR, }); } }, [uploadFile, showToast, localize, queryClient], ); const handleFileChange = useCallback( (event: React.ChangeEvent) => { const file = event.target.files?.[0]; if (file) { setIsUploading(true); handleFileUpload(file); } event.target.value = ''; }, [handleFileUpload], ); const handleImportClick = useCallback(() => { fileInputRef.current?.click(); }, []); const handleKeyDown = useCallback( (event: React.KeyboardEvent) => { if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); handleImportClick(); } }, [handleImportClick], ); const isImportDisabled = isUploading; return (
); } export default ImportConversations;