'use client' import { useState, useEffect } from 'react' import { createPortal } from 'react-dom' import { NoteChartFromCode } from './note-chart' import { suggestCharts, chartSuggestionToMarkdown, type ChartSuggestion, type SuggestChartsResponse } from '@/lib/ai/services/chart-suggestion.service' import { BarChart3, X, Search, AlertCircle } from 'lucide-react' import { cn } from '@/lib/utils' interface ChartSuggestionsDialogProps { isOpen: boolean content: string selection: string | null noteId?: string onClose: () => void onSelectChart: (markdown: string) => void } export function ChartSuggestionsDialog({ isOpen, content, selection, noteId, onClose, onSelectChart, }: ChartSuggestionsDialogProps) { const [response, setResponse] = useState(null) const [loading, setLoading] = useState(false) const [selectedIndex, setSelectedIndex] = useState(null) // Reset state when dialog opens useEffect(() => { let aborted = false if (isOpen) { setResponse(null) setLoading(true) setSelectedIndex(null) // Call the suggestion API suggestCharts({ content, selection, noteId }) .then(data => { if (aborted) return setResponse(data) setLoading(false) }) .catch(err => { if (aborted) return console.error('[ChartSuggestionsDialog] Error:', err) setResponse({ suggestions: [], analyzedText: '', detectedData: '', hasData: false, error: err.message || 'Failed to load suggestions', }) setLoading(false) }) } return () => { aborted = true } }, [isOpen, content, selection, noteId]) // Handle keyboard shortcuts useEffect(() => { if (!isOpen) return const handleKeyDown = (e: KeyboardEvent) => { if (e.key === 'Escape') { onClose() } if (e.key === 'ArrowRight' && response?.suggestions) { setSelectedIndex(i => i === null ? 0 : (i + 1) % response.suggestions.length) } if (e.key === 'ArrowLeft' && response?.suggestions) { setSelectedIndex(i => i === null ? 0 : (i === 0 ? response.suggestions.length - 1 : i - 1)) } if (e.key === 'Enter' && selectedIndex !== null && response?.suggestions?.[selectedIndex]) { onSelectChart(chartSuggestionToMarkdown(response.suggestions[selectedIndex])) onClose() } } document.addEventListener('keydown', handleKeyDown) return () => document.removeEventListener('keydown', handleKeyDown) }, [isOpen, onClose, selectedIndex, response, onSelectChart]) if (!isOpen) return null const textToAnalyze = selection || content const isAnalyzingSelection = !!selection const wordCount = textToAnalyze.split(/\s+/).length const handleSelectChart = (suggestion: ChartSuggestion) => { onSelectChart(chartSuggestionToMarkdown(suggestion)) onClose() } return createPortal(
e.stopPropagation()} > {/* Header */}

Chart Suggestions

{loading ? ( Analyzing {isAnalyzingSelection ? 'selection' : 'note'} ({wordCount} words)... ) : response?.hasData ? ( `Found ${response?.detectedData || 'data'}` ) : ( 'No data detected' )}

{/* Content */}
{loading ? (

Analyzing your content for chart data...

) : response?.error ? (

Error

{response.error}

) : !response?.hasData ? (

No Data Detected

Try adding numerical data to your note. Charts work best with:

  • • Sales figures, metrics, or measurements
  • • Lists with values (e.g., "Jan: 5000, Feb: 7500")
  • • Percentages or proportions
  • • Time-series data
) : (

Select a chart type to insert:

{/* Chart suggestions grid */}
{response.suggestions.map((suggestion, index) => { const isSelected = selectedIndex === index const markdown = chartSuggestionToMarkdown(suggestion) return ( ) })}
{/* Keyboard hint */}
← → Navigate ↵ Select Esc Cancel
)}
, document.body ) }