import React, { useState, useEffect, useCallback } from 'react'; import Editor from '@monaco-editor/react'; import { Button } from '@/components/ui/button'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; interface AdvancedEditorProps { value: string; onChange: (value: string) => void; language?: string; placeholder?: string; height?: string; autoSave?: boolean; onSave?: (value: string) => void; className?: string; } export const AdvancedEditor: React.FC = ({ value, onChange, language = 'markdown', placeholder = 'Start typing...', height = '400px', autoSave = false, onSave, className = '', }) => { const [editorValue, setEditorValue] = useState(value); const [viewMode, setViewMode] = useState<'edit' | 'preview' | 'split'>('edit'); const [isModified, setIsModified] = useState(false); const [lastSaved, setLastSaved] = useState(null); // Auto-save functionality useEffect(() => { if (autoSave && isModified && onSave) { const timeout = setTimeout(() => { onSave(editorValue); setLastSaved(new Date()); setIsModified(false); }, 2000); // Auto-save after 2 seconds of inactivity return () => clearTimeout(timeout); } }, [editorValue, autoSave, isModified, onSave]); // Update editor when external value changes useEffect(() => { if (value !== editorValue) { setEditorValue(value); setIsModified(false); } }, [value]); const handleEditorChange = useCallback((newValue: string | undefined) => { if (newValue !== undefined) { setEditorValue(newValue); onChange(newValue); setIsModified(true); } }, [onChange]); const handleSave = useCallback(() => { if (onSave) { onSave(editorValue); setLastSaved(new Date()); setIsModified(false); } }, [editorValue, onSave]); const detectLanguage = (content: string): string => { // Simple language detection based on content patterns if (content.includes('```javascript') || content.includes('```js')) return 'javascript'; if (content.includes('```typescript') || content.includes('```ts')) return 'typescript'; if (content.includes('```python') || content.includes('```py')) return 'python'; if (content.includes('```json')) return 'json'; if (content.includes('```yaml') || content.includes('```yml')) return 'yaml'; if (content.includes('```css')) return 'css'; if (content.includes('```html')) return 'html'; if (content.includes('```sql')) return 'sql'; if (content.includes('```bash') || content.includes('```sh')) return 'shell'; // Check for common programming patterns if (/function\s+\w+\s*\(/.test(content) || /const\s+\w+\s*=/.test(content)) return 'javascript'; if (/def\s+\w+\s*\(/.test(content) || /import\s+\w+/.test(content)) return 'python'; if (/\{[\s\S]*"[\w]+"\s*:/.test(content)) return 'json'; return 'markdown'; }; const renderPreview = () => { // Simple markdown-like preview (in a real app, use a proper markdown library) return (
          {editorValue || placeholder}
        
); }; const editorOptions = { minimap: { enabled: false }, fontSize: 14, lineHeight: 1.6, wordWrap: 'on' as const, theme: 'vs-dark', automaticLayout: true, scrollBeyondLastLine: false, folding: true, lineNumbers: 'on' as const, renderWhitespace: 'selection' as const, bracketPairColorization: { enabled: true }, suggest: { showKeywords: true, showSnippets: true, }, }; return (
{/* Editor Header */}
{/* View Mode Tabs */} setViewMode(mode as any)} className="w-auto"> Edit Preview Split {/* Language Detection */}
{detectLanguage(editorValue)}
{/* Save Status */} {isModified && ( Unsaved changes )} {lastSaved && !isModified && ( Saved {lastSaved.toLocaleTimeString()} )} {/* Manual Save Button */} {onSave && ( )}
{/* Editor Content */}
{viewMode === 'edit' && ( )} {viewMode === 'preview' && renderPreview()} {viewMode === 'split' && (
{renderPreview()}
)}
{/* Editor Footer */}
Lines: {editorValue.split('\n').length} Characters: {editorValue.length} Words: {editorValue.split(/\s+/).filter(Boolean).length}
{autoSave && ( Auto-save enabled )} Ctrl+S to save
); }; export default AdvancedEditor;