'use client' import { useState, useEffect } from 'react' import { createPortal } from 'react-dom' import { NoteChart } from './note-chart' import { suggestCharts, chartSuggestionToMarkdown, type ChartSuggestion, type SuggestChartsResponse } from '@/lib/ai/services/chart-suggestion.service' import { BarChart3, X, Search, AlertCircle, Sparkles } from 'lucide-react' import { cn } from '@/lib/utils' // Chart type to color mapping for visual variety const CHART_TYPE_COLORS: Record = { bar: 'bg-blue-500/10 text-blue-600 border-blue-500/20', 'horizontal-bar': 'bg-indigo-500/10 text-indigo-600 border-indigo-500/20', line: 'bg-emerald-500/10 text-emerald-600 border-emerald-500/20', area: 'bg-teal-500/10 text-teal-600 border-teal-500/20', pie: 'bg-violet-500/10 text-violet-600 border-violet-500/20', radar: 'bg-fuchsia-500/10 text-fuchsia-600 border-fuchsia-500/20', funnel: 'bg-amber-500/10 text-amber-600 border-amber-500/20', gauge: 'bg-rose-500/10 text-rose-600 border-rose-500/20', } 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 console.log('[ChartSuggestionsDialog] Response:', data) setResponse(data) setLoading(false) }) .catch(err => { if (aborted) return console.error('[ChartSuggestionsDialog] Error:', err) setResponse({ suggestions: [], analyzedText: textToAnalyze?.substring(0, 100) || '', detectedData: 'Error occurred', hasData: false, error: err.message || 'Network error - check console', }) 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?.quotaExceeded ? (

AI Quota Exceeded

{response.error || 'You have reached your AI usage limit.'}

) : response?.error ? (

Error

{response.error}

Debug info
                    analyzedText: {response.analyzedText}
                    {'\n'}detectedData: {response.detectedData}
                  
) : !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
Debug: Show what was analyzed
                      {textToAnalyze.substring(0, 500)}
                      {textToAnalyze.length > 500 && '...'}
                    
) : (

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 ) }