Spaces:
Sleeping
Sleeping
| import React, { useState } from 'react'; | |
| import { Button } from './ui/button'; | |
| import { Download, ClipboardList, Sparkles } from 'lucide-react'; | |
| import { toast } from 'sonner@2.0.3'; | |
| import type { User } from '../App'; | |
| interface FloatingActionButtonsProps { | |
| user: User | null; | |
| isLoggedIn: boolean; | |
| onOpenPanel: () => void; | |
| onExport: () => void; | |
| onQuiz: () => void; | |
| onSummary: () => void; | |
| } | |
| export function FloatingActionButtons({ | |
| user, | |
| isLoggedIn, | |
| onOpenPanel, | |
| onExport, | |
| onQuiz, | |
| onSummary, | |
| }: FloatingActionButtonsProps) { | |
| const [hoveredButton, setHoveredButton] = useState<string | null>(null); | |
| const handleAction = (action: () => void, actionName: string, shouldOpenPanel: boolean = false) => { | |
| if (!isLoggedIn) { | |
| toast.error('Please log in to use this feature'); | |
| return; | |
| } | |
| action(); | |
| if (shouldOpenPanel) { | |
| onOpenPanel(); | |
| } | |
| }; | |
| const buttons = [ | |
| { | |
| id: 'export', | |
| icon: Download, | |
| label: 'Export Conversation', | |
| action: onExport, | |
| openPanel: true, // Open panel for export | |
| }, | |
| { | |
| id: 'quiz', | |
| icon: ClipboardList, | |
| label: "Let's Try (Micro-Quiz)", | |
| action: onQuiz, | |
| openPanel: false, // Don't open panel for quiz | |
| }, | |
| { | |
| id: 'summary', | |
| icon: Sparkles, | |
| label: 'Summarization', | |
| action: onSummary, | |
| openPanel: true, // Open panel for summary | |
| }, | |
| ]; | |
| return ( | |
| <div className="fixed right-4 bottom-[28rem] z-40 flex flex-col gap-2"> | |
| {buttons.map((button, index) => { | |
| const Icon = button.icon; | |
| const isHovered = hoveredButton === button.id; | |
| return ( | |
| <div | |
| key={button.id} | |
| className="relative group" | |
| onMouseEnter={() => setHoveredButton(button.id)} | |
| onMouseLeave={() => setHoveredButton(null)} | |
| > | |
| {/* Tooltip */} | |
| <div | |
| className={` | |
| absolute right-full mr-3 top-1/2 -translate-y-1/2 | |
| px-3 py-2 rounded-lg bg-popover border border-border | |
| whitespace-nowrap text-sm shadow-lg | |
| transition-all duration-200 | |
| ${isHovered ? 'opacity-100 translate-x-0' : 'opacity-0 translate-x-2 pointer-events-none'} | |
| `} | |
| > | |
| {button.label} | |
| </div> | |
| {/* Floating Button */} | |
| <Button | |
| size="icon" | |
| className={` | |
| h-6 w-6 rounded-full shadow-md opacity-60 hover:opacity-100 | |
| transition-all duration-200 | |
| ${isLoggedIn | |
| ? 'bg-primary hover:bg-primary/90 text-primary-foreground' | |
| : 'bg-muted hover:bg-muted/90 text-muted-foreground' | |
| } | |
| ${isHovered ? 'scale-110' : 'scale-100'} | |
| `} | |
| onClick={() => handleAction(button.action, button.label, button.openPanel)} | |
| style={{ | |
| animationDelay: `${index * 100}ms`, | |
| }} | |
| > | |
| <Icon className="h-3 w-3" /> | |
| </Button> | |
| </div> | |
| ); | |
| })} | |
| </div> | |
| ); | |
| } |