diff --git a/src/ui/components.tsx b/src/ui/components.tsx index e280c55..0fb9cd8 100644 --- a/src/ui/components.tsx +++ b/src/ui/components.tsx @@ -5,6 +5,8 @@ import { CustomContextMenu } from "./CustomContextMenu" import { FocusLockIndicator } from "./FocusLockIndicator" import { MycelialIntelligenceBar } from "./MycelialIntelligenceBar" import { CommandPalette } from "./CommandPalette" +import { UserSettingsModal } from "./UserSettingsModal" +import { GoogleExportBrowser } from "../components/GoogleExportBrowser" import { DefaultKeyboardShortcutsDialog, DefaultKeyboardShortcutsDialogContent, @@ -17,15 +19,77 @@ import { } from "tldraw" import { SlidesPanel } from "@/slides/SlidesPanel" -// Custom People Menu component for showing connected users +// Custom People Menu component for showing connected users and integrations function CustomPeopleMenu() { const editor = useEditor() const [showDropdown, setShowDropdown] = React.useState(false) + const [showGoogleBrowser, setShowGoogleBrowser] = React.useState(false) + const [googleConnected, setGoogleConnected] = React.useState(false) + const [googleLoading, setGoogleLoading] = React.useState(false) + + // Detect dark mode + const isDarkMode = typeof document !== 'undefined' && + document.documentElement.classList.contains('dark') // Get current user info const myUserColor = useValue('myColor', () => editor.user.getColor(), [editor]) const myUserName = useValue('myName', () => editor.user.getName() || 'You', [editor]) + // Check Google connection on mount + React.useEffect(() => { + const checkGoogleStatus = async () => { + try { + const { GoogleDataService } = await import('../lib/google') + const service = GoogleDataService.getInstance() + const isAuthed = await service.isAuthenticated() + setGoogleConnected(isAuthed) + } catch (error) { + console.warn('Failed to check Google status:', error) + } + } + checkGoogleStatus() + }, []) + + const handleGoogleConnect = async () => { + setGoogleLoading(true) + try { + const { GoogleDataService } = await import('../lib/google') + const service = GoogleDataService.getInstance() + await service.authenticate() + setGoogleConnected(true) + } catch (error) { + console.error('Google auth failed:', error) + } finally { + setGoogleLoading(false) + } + } + + const handleOpenGoogleBrowser = () => { + setShowDropdown(false) + setShowGoogleBrowser(true) + } + + const handleAddToCanvas = async (items: any[], position: { x: number; y: number }) => { + try { + const { createGoogleItemProps } = await import('../shapes/GoogleItemShapeUtil') + + // Create shapes for each selected item + items.forEach((item, index) => { + const props = createGoogleItemProps(item, 'local') + editor.createShape({ + type: 'GoogleItem', + x: position.x + (index % 3) * 240, + y: position.y + Math.floor(index / 3) * 160, + props, + }) + }) + + setShowGoogleBrowser(false) + } catch (error) { + console.error('Failed to add items to canvas:', error) + } + } + // Get all collaborators (other users in the session) const collaborators = useValue('collaborators', () => editor.getCollaborators(), [editor]) @@ -199,9 +263,128 @@ function CustomPeopleMenu() { ))} + + {/* Separator */} +
+ + {/* Google Workspace Section */} +