import { useState, useEffect, useRef } from 'react' import { motion, AnimatePresence } from 'framer-motion' import Editor from '@monaco-editor/react' import { FaPlay, FaSave, FaDownload, FaUpload, FaCopy, FaTerminal, FaCode, FaBug, FaCheckCircle, FaExclamationTriangle, FaCog, FaFolderOpen, FaFile, FaFileCode, FaJs, FaPython, FaJava, FaHtml5, FaCss3Alt, FaReact, FaNodeJs, FaGitAlt, FaDatabase } from 'react-icons/fa' import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter' import { vscDarkPlus } from 'react-syntax-highlighter/dist/cjs/styles/prism' import toast from 'react-hot-toast' export default function CodeEditor({ language, theme }) { const [code, setCode] = useState(`// ${language === 'fa' ? 'کد خود را اینجا بنویسید' : 'Write your code here'}\nfunction hello() {\n console.log("Hello, World!");\n}`) const [output, setOutput] = useState('') const [isRunning, setIsRunning] = useState(false) const [selectedLanguage, setSelectedLanguage] = useState('javascript') const [files, setFiles] = useState([ { id: 1, name: 'main.js', content: code, language: 'javascript' }, { id: 2, name: 'utils.py', content: '# Python utilities', language: 'python' } ]) const [activeFile, setActiveFile] = useState(1) const [fontSize, setFontSize] = useState(14) const [theme, setEditorTheme] = useState('vs-dark') const [showTerminal, setShowTerminal] = useState(true) const [errors, setErrors] = useState([]) const editorRef = useRef(null) const languages = [ { id: 'javascript', name: 'JavaScript', icon: FaJs, color: 'text-yellow-400' }, { id: 'python', name: 'Python', icon: FaPython, color: 'text-blue-400' }, { id: 'java', name: 'Java', icon: FaJava, color: 'text-red-400' }, { id: 'html', name: 'HTML', icon: FaHtml5, color: 'text-orange-500' }, { id: 'css', name: 'CSS', icon: FaCss3Alt, color: 'text-blue-500' }, { id: 'typescript', name: 'TypeScript', icon: FaCode, color: 'text-blue-600' }, { id: 'json', name: 'JSON', icon: FaDatabase, color: 'text-green-500' }, { id: 'sql', name: 'SQL', icon: FaDatabase, color: 'text-purple-500' } ] const handleEditorDidMount = (editor, monaco) => { editorRef.current = editor editor.focus() } const runCode = async () => { setIsRunning(true) setOutput('') setErrors([]) try { // Simulate code execution await new Promise(resolve => setTimeout(resolve, 2000)) if (selectedLanguage === 'javascript') { // Safe eval simulation const result = 'Code executed successfully!\nOutput: Hello, World!' setOutput(result) toast.success(language === 'fa' ? 'کد با موفقیت اجرا شد' : 'Code executed successfully') } else { setOutput(`${selectedLanguage.toUpperCase()} code execution simulated`) } } catch (error) { setErrors([error.message]) toast.error(language === 'fa' ? 'خطا در اجرای کد' : 'Error executing code') } finally { setIsRunning(false) } } const saveCode = () => { const updatedFiles = files.map(file => file.id === activeFile ? { ...file, content: code } : file ) setFiles(updatedFiles) toast.success(language === 'fa' ? 'کد ذخیره شد' : 'Code saved') } const downloadCode = () => { const file = files.find(f => f.id === activeFile) const blob = new Blob([code], { type: 'text/plain' }) const url = URL.createObjectURL(blob) const a = document.createElement('a') a.href = url a.download = file.name a.click() toast.success(language === 'fa' ? 'کد دانلود شد' : 'Code downloaded') } const uploadFile = (event) => { const file = event.target.files[0] if (file) { const reader = new FileReader() reader.onload = (e) => { const content = e.target.result const newFile = { id: Date.now(), name: file.name, content: content, language: selectedLanguage } setFiles([...files, newFile]) setActiveFile(newFile.id) setCode(content) toast.success(language === 'fa' ? 'فایل آپلود شد' : 'File uploaded') } reader.readAsText(file) } } const createNewFile = () => { const newFile = { id: Date.now(), name: `untitled.${selectedLanguage === 'javascript' ? 'js' : selectedLanguage}`, content: `// New ${selectedLanguage} file`, language: selectedLanguage } setFiles([...files, newFile]) setActiveFile(newFile.id) setCode(newFile.content) } const deleteFile = (fileId) => { if (files.length > 1) { setFiles(files.filter(f => f.id !== fileId)) if (activeFile === fileId) { setActiveFile(files[0].id) setCode(files[0].content) } toast.success(language === 'fa' ? 'فایل حذف شد' : 'File deleted') } } useEffect(() => { const activeFileData = files.find(f => f.id === activeFile) if (activeFileData) { setCode(activeFileData.content) setSelectedLanguage(activeFileData.language) } }, [activeFile]) return (
{/* Toolbar */}
{/* File Tabs */}
{files.map(file => ( )} ))}
{/* Editor and Output */}
{/* Code Editor */}
setCode(value)} onMount={handleEditorDidMount} theme={theme} options={{ fontSize, minimap: { enabled: false }, scrollBeyondLastLine: false, automaticLayout: true, tabSize: 2, wordWrap: 'on', lineNumbers: 'on', folding: true, renderWhitespace: 'selection', />
{/* Terminal/Output */} {showTerminal && (
{language === 'fa' ? 'خروجی' : 'Output'}
{isRunning && (
)} {errors.length === 0 && output && ( )} {errors.length > 0 && ( )}
{errors.length > 0 ? (
{errors.map((error, index) => (
Error: {error}
))}
) : output ? (
{output}
) : (
{language === 'fa' ? 'کد را اجرا کنید تا خروجی نمایش داده شود' : 'Run the code to see output'}
)}
)}
) }