|
| 1 | + |
1 | 2 | import { useTheme } from "../../Contexts/ThemeProvider"; |
2 | 3 |
|
3 | | -const CompilerPanel = () => { |
| 4 | +import { useState } from "react"; |
| 5 | +import { useEditorCollaboration } from "../../Contexts/EditorContext"; |
| 6 | +import type { FileNode } from "./ProjectManagementPanel/file.types"; |
| 7 | +import axios from "axios"; |
| 8 | + |
| 9 | +type CompilerPanelProps = { |
| 10 | + selectedFile?: FileNode | null; |
| 11 | +}; |
| 12 | + |
| 13 | +const CompilerPanel = ({ selectedFile }: CompilerPanelProps) => { |
4 | 14 | const { theme } = useTheme(); |
| 15 | + const [output, setOutput] = useState<string>(""); |
| 16 | + const [loading, setLoading] = useState(false); |
| 17 | + const [error, setError] = useState<string>(""); |
| 18 | + const [isSuccess, setIsSuccess] = useState<boolean | null>(null); |
| 19 | + const { getFileText } = useEditorCollaboration(); |
| 20 | + |
| 21 | + // Get selected file content |
| 22 | + const code = selectedFile?.id ? getFileText(selectedFile.id)?.toString() : ""; |
| 23 | + // Determine language from file extension |
| 24 | + const extension = selectedFile?.name?.split(".").pop()?.toLowerCase(); |
| 25 | + const languageMap: Record<string, string> = { |
| 26 | + js: "javascript", |
| 27 | + jsx: "javascript", |
| 28 | + py: "python", |
| 29 | + java: "java", |
| 30 | + |
| 31 | + }; |
| 32 | + const language = languageMap[extension || ""] || "plaintext"; |
| 33 | + console.log(code, language); |
| 34 | + const handleRun = async () => { |
| 35 | + setLoading(true); |
| 36 | + setError(""); |
| 37 | + setOutput(""); |
| 38 | + setIsSuccess(null); |
| 39 | + try { |
| 40 | + const res = await axios.post("http://localhost:4000/run", { |
| 41 | + language, |
| 42 | + code, |
| 43 | + input: "" |
| 44 | + }); |
| 45 | + const data = res.data; |
| 46 | + let out = ""; |
| 47 | + let success = false; |
| 48 | + if (data?.result?.output !== undefined) { |
| 49 | + out = data.result.output; |
| 50 | + success = data.result.success !== false; |
| 51 | + } else if (data.output !== undefined) { |
| 52 | + out = data.output; |
| 53 | + success = data.success !== false; |
| 54 | + } else { |
| 55 | + out = JSON.stringify(data, null, 2); |
| 56 | + } |
| 57 | + setOutput(out); |
| 58 | + setIsSuccess(success); |
| 59 | + } catch (e: any) { |
| 60 | + setError(e.message || "Unknown error"); |
| 61 | + setIsSuccess(false); |
| 62 | + } finally { |
| 63 | + setLoading(false); |
| 64 | + } |
| 65 | + }; |
5 | 66 |
|
6 | 67 | return ( |
7 | 68 | <div className={`h-full ${theme.surface} ${theme.text} p-4`}> |
8 | 69 | <h3 className="text-sm font-medium mb-2">Compiler</h3> |
9 | | - <div className={`text-xs ${theme.textMuted}`}> |
10 | | - Compiler input and output will go here |
| 70 | + <button |
| 71 | + className={`mb-2 px-3 py-1 rounded ${theme.surfaceSecondary} ${theme.text}`} |
| 72 | + onClick={handleRun} |
| 73 | + disabled={loading || !code} |
| 74 | + > |
| 75 | + {loading ? "Running..." : "Run Code"} |
| 76 | + </button> |
| 77 | + <div className={`text-xs ${theme.textMuted} mb-2`}> |
| 78 | + {selectedFile?.name ? `File: ${selectedFile.name}` : "No file selected"} |
11 | 79 | </div> |
| 80 | + {error && ( |
| 81 | + <div className="text-xs font-semibold mb-2" style={{ color: '#ef4444' }}>Error: {error}</div> |
| 82 | + )} |
| 83 | + {output && ( |
| 84 | + <div |
| 85 | + className={`text-xs font-mono whitespace-pre-wrap px-3 py-2 rounded mb-2`} |
| 86 | + style={{ |
| 87 | + background: isSuccess === true ? '#052e16' : '#7f1d1d', |
| 88 | + color: isSuccess === true ? '#22c55e' : '#f87171', |
| 89 | + border: `1px solid ${isSuccess === true ? '#22c55e' : '#f87171'}`, |
| 90 | + fontWeight: 600, |
| 91 | + }} |
| 92 | + > |
| 93 | + {isSuccess === true ? 'Output: ' : 'Error: '} |
| 94 | + {output} |
| 95 | + </div> |
| 96 | + )} |
| 97 | + {!output && !error && ( |
| 98 | + <div className={`text-xs ${theme.textMuted}`}>Output will appear here</div> |
| 99 | + )} |
12 | 100 | </div> |
13 | 101 | ); |
14 | 102 | }; |
|
0 commit comments