"use client" import { useState, useEffect } from "react" import { Button } from "@/components/ui/button" import { Badge } from "@/components/ui/badge" import { FileText, Folder, Trash2, X } from "lucide-react" interface OneDrivePickerProps { onFileSelected: (files: OneDriveFile[]) => void selectedFiles?: OneDriveFile[] isAuthenticated: boolean accessToken?: string connectorType?: "onedrive" | "sharepoint" onPickerStateChange?: (isOpen: boolean) => void } interface OneDriveFile { id: string name: string mimeType?: string webUrl?: string driveItem?: { file?: { mimeType: string } folder?: unknown } } interface GraphResponse { value: OneDriveFile[] } declare global { interface Window { mgt?: { Providers?: { globalProvider?: unknown } } } } export function OneDrivePicker({ onFileSelected, selectedFiles = [], isAuthenticated, accessToken, connectorType = "onedrive", onPickerStateChange }: OneDrivePickerProps) { const [isLoading, setIsLoading] = useState(false) const [files, setFiles] = useState([]) const [isPickerOpen, setIsPickerOpen] = useState(false) const [currentPath, setCurrentPath] = useState( connectorType === "sharepoint" ? 'sites?search=' : 'me/drive/root/children' ) const [breadcrumbs, setBreadcrumbs] = useState<{id: string, name: string}[]>([ {id: 'root', name: connectorType === "sharepoint" ? 'SharePoint' : 'OneDrive'} ]) useEffect(() => { const loadMGT = async () => { if (typeof window !== 'undefined' && !window.mgt) { try { await import('@microsoft/mgt-components') await import('@microsoft/mgt-msal2-provider') // For simplicity, we'll use direct Graph API calls instead of MGT components // MGT provider initialization would go here if needed } catch { console.warn('MGT not available, falling back to direct API calls') } } } loadMGT() }, [accessToken]) const fetchFiles = async (path: string = currentPath) => { if (!accessToken) return setIsLoading(true) try { const response = await fetch(`https://graph.microsoft.com/v1.0/${path}`, { headers: { 'Authorization': `Bearer ${accessToken}`, 'Content-Type': 'application/json' } }) if (response.ok) { const data: GraphResponse = await response.json() setFiles(data.value || []) } else { console.error('Failed to fetch OneDrive files:', response.statusText) } } catch (error) { console.error('Error fetching OneDrive files:', error) } finally { setIsLoading(false) } } const openPicker = () => { if (!accessToken) return setIsPickerOpen(true) onPickerStateChange?.(true) fetchFiles() } const closePicker = () => { setIsPickerOpen(false) onPickerStateChange?.(false) setFiles([]) setCurrentPath( connectorType === "sharepoint" ? 'sites?search=' : 'me/drive/root/children' ) setBreadcrumbs([ {id: 'root', name: connectorType === "sharepoint" ? 'SharePoint' : 'OneDrive'} ]) } const handleFileClick = (file: OneDriveFile) => { if (file.driveItem?.folder) { // Navigate to folder const newPath = `me/drive/items/${file.id}/children` setCurrentPath(newPath) setBreadcrumbs([...breadcrumbs, {id: file.id, name: file.name}]) fetchFiles(newPath) } else { // Select file const isAlreadySelected = selectedFiles.some(f => f.id === file.id) if (!isAlreadySelected) { onFileSelected([...selectedFiles, file]) } } } const navigateToBreadcrumb = (index: number) => { if (index === 0) { setCurrentPath('me/drive/root/children') setBreadcrumbs([{id: 'root', name: 'OneDrive'}]) fetchFiles('me/drive/root/children') } else { const targetCrumb = breadcrumbs[index] const newPath = `me/drive/items/${targetCrumb.id}/children` setCurrentPath(newPath) setBreadcrumbs(breadcrumbs.slice(0, index + 1)) fetchFiles(newPath) } } const removeFile = (fileId: string) => { const updatedFiles = selectedFiles.filter(file => file.id !== fileId) onFileSelected(updatedFiles) } const getFileIcon = (file: OneDriveFile) => { if (file.driveItem?.folder) { return } return } const getMimeTypeLabel = (file: OneDriveFile) => { const mimeType = file.driveItem?.file?.mimeType || file.mimeType || '' const typeMap: { [key: string]: string } = { 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'Word Doc', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'Excel', 'application/vnd.openxmlformats-officedocument.presentationml.presentation': 'PowerPoint', 'application/pdf': 'PDF', 'text/plain': 'Text', 'image/jpeg': 'Image', 'image/png': 'Image', } if (file.driveItem?.folder) return 'Folder' return typeMap[mimeType] || 'Document' } const serviceName = connectorType === "sharepoint" ? "SharePoint" : "OneDrive" if (!isAuthenticated) { return (
Please connect to {serviceName} first to select specific files.
) } return (

{serviceName} File Selection

Choose specific files to sync instead of syncing everything

{/* Status message when access token is missing */} {isAuthenticated && !accessToken && (
Access token unavailable
The file picker requires an access token. Try disconnecting and reconnecting your {serviceName} account.
)} {/* File Picker Modal */} {isPickerOpen && (

Select Files from {serviceName}

{/* Breadcrumbs */}
{breadcrumbs.map((crumb, index) => (
{index > 0 && /}
))}
{/* File List */}
{isLoading ? (
Loading...
) : files.length === 0 ? (
No files found
) : (
{files.map((file) => (
handleFileClick(file)} >
{getFileIcon(file)} {file.name} {getMimeTypeLabel(file)}
{selectedFiles.some(f => f.id === file.id) && ( Selected )}
))}
)}
)} {selectedFiles.length > 0 && (

Selected files ({selectedFiles.length}):

{selectedFiles.map((file) => (
{getFileIcon(file)} {file.name} {getMimeTypeLabel(file)}
))}
)}
) }