"use client" import { useState, useEffect } from "react" import { useParams, useRouter } from "next/navigation" import { Button } from "@/components/ui/button" import { ArrowLeft, AlertCircle } from "lucide-react" import { GoogleDrivePicker } from "@/components/google-drive-picker" import { OneDrivePicker } from "@/components/onedrive-picker" import { useTask } from "@/contexts/task-context" import { Toast } from "@/components/ui/toast" interface GoogleDriveFile { id: string name: string mimeType: string webViewLink?: string iconLink?: string } interface OneDriveFile { id: string name: string mimeType?: string webUrl?: string driveItem?: { file?: { mimeType: string } folder?: unknown } } interface CloudConnector { id: string name: string description: string status: "not_connected" | "connecting" | "connected" | "error" type: string connectionId?: string clientId: string hasAccessToken: boolean accessTokenError?: string } export default function UploadProviderPage() { const params = useParams() const router = useRouter() const provider = params.provider as string const { addTask, tasks } = useTask() const [connector, setConnector] = useState(null) const [isLoading, setIsLoading] = useState(true) const [error, setError] = useState(null) const [accessToken, setAccessToken] = useState(null) const [selectedFiles, setSelectedFiles] = useState([]) const [isIngesting, setIsIngesting] = useState(false) const [currentSyncTaskId, setCurrentSyncTaskId] = useState(null) const [showSuccessToast, setShowSuccessToast] = useState(false) useEffect(() => { const fetchConnectorInfo = async () => { setIsLoading(true) setError(null) try { // Fetch available connectors to validate the provider const connectorsResponse = await fetch('/api/connectors') if (!connectorsResponse.ok) { throw new Error('Failed to load connectors') } const connectorsResult = await connectorsResponse.json() const providerInfo = connectorsResult.connectors[provider] if (!providerInfo || !providerInfo.available) { setError(`Cloud provider "${provider}" is not available or configured.`) return } // Check connector status const statusResponse = await fetch(`/api/connectors/${provider}/status`) if (!statusResponse.ok) { throw new Error(`Failed to check ${provider} status`) } const statusData = await statusResponse.json() const connections = statusData.connections || [] const activeConnection = connections.find((conn: {is_active: boolean, connection_id: string}) => conn.is_active) const isConnected = activeConnection !== undefined let hasAccessToken = false let accessTokenError: string | undefined = undefined // Try to get access token for connected connectors if (isConnected && activeConnection) { try { const tokenResponse = await fetch(`/api/connectors/${provider}/token?connection_id=${activeConnection.connection_id}`) if (tokenResponse.ok) { const tokenData = await tokenResponse.json() if (tokenData.access_token) { hasAccessToken = true setAccessToken(tokenData.access_token) } } else { const errorData = await tokenResponse.json().catch(() => ({ error: 'Token unavailable' })) accessTokenError = errorData.error || 'Access token unavailable' } } catch { accessTokenError = 'Failed to fetch access token' } } setConnector({ id: provider, name: providerInfo.name, description: providerInfo.description, status: isConnected ? "connected" : "not_connected", type: provider, connectionId: activeConnection?.connection_id, clientId: activeConnection?.client_id, hasAccessToken, accessTokenError }) } catch (error) { console.error('Failed to load connector info:', error) setError(error instanceof Error ? error.message : 'Failed to load connector information') } finally { setIsLoading(false) } } if (provider) { fetchConnectorInfo() } }, [provider]) // Watch for sync task completion and redirect useEffect(() => { if (!currentSyncTaskId) return const currentTask = tasks.find(task => task.task_id === currentSyncTaskId) if (currentTask && currentTask.status === 'completed') { // Task completed successfully, show toast and redirect setIsIngesting(false) setShowSuccessToast(true) setTimeout(() => { router.push('/knowledge') }, 2000) // 2 second delay to let user see toast } else if (currentTask && currentTask.status === 'failed') { // Task failed, clear the tracking but don't redirect setIsIngesting(false) setCurrentSyncTaskId(null) } }, [tasks, currentSyncTaskId, router]) const handleFileSelected = (files: GoogleDriveFile[] | OneDriveFile[]) => { setSelectedFiles(files) console.log(`Selected ${files.length} files from ${provider}:`, files) // You can add additional handling here like triggering sync, etc. } const handleGoogleDriveFileSelected = (files: GoogleDriveFile[]) => { handleFileSelected(files) } const handleOneDriveFileSelected = (files: OneDriveFile[]) => { handleFileSelected(files) } const handleSync = async (connector: CloudConnector) => { if (!connector.connectionId || selectedFiles.length === 0) return setIsIngesting(true) try { const syncBody: { connection_id: string; max_files?: number; selected_files?: string[]; } = { connection_id: connector.connectionId, selected_files: selectedFiles.map(file => file.id) } const response = await fetch(`/api/connectors/${connector.type}/sync`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(syncBody), }) const result = await response.json() if (response.status === 201) { const taskIds = result.task_ids if (taskIds && taskIds.length > 0) { const taskId = taskIds[0] // Use the first task ID addTask(taskId) setCurrentSyncTaskId(taskId) } } else { console.error('Sync failed:', result.error) } } catch (error) { console.error('Sync error:', error) setIsIngesting(false) } } const getProviderDisplayName = () => { const nameMap: { [key: string]: string } = { 'google_drive': 'Google Drive', 'onedrive': 'OneDrive', 'sharepoint': 'SharePoint' } return nameMap[provider] || provider } if (isLoading) { return (

Loading {getProviderDisplayName()} connector...

) } if (error || !connector) { return (

Provider Not Available

{error}

) } if (connector.status !== "connected") { return (

{connector.name} Not Connected

You need to connect your {connector.name} account before you can select files.

) } if (!connector.hasAccessToken) { return (

Access Token Required

{connector.accessTokenError || `Unable to get access token for ${connector.name}. Try reconnecting your account.`}

) } return (

Add Cloud Knowledge

{connector.type === "google_drive" && ( )} {(connector.type === "onedrive" || connector.type === "sharepoint") && ( )}
{selectedFiles.length > 0 && (
)} {/* Success toast notification */} setShowSuccessToast(false)} duration={20000} />
) }