Skip to content

Commit d28fae4

Browse files
committed
Linting check fix attempt 1
1 parent a4dad82 commit d28fae4

File tree

1 file changed

+182
-54
lines changed

1 file changed

+182
-54
lines changed

src/pages/EditorComponent.js

Lines changed: 182 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
// src/pages/EditorComponent.js
2-
// (All your existing imports remain the same)
32
import React, { useCallback, useEffect, useRef, useState } from "react";
43
import { useSnackbar } from "notistack";
54
import {
@@ -88,7 +87,6 @@ function EditorComponent() {
8887
const [showLineNumbers, setShowLineNumbers] = useState(true);
8988
const [wordWrap, setWordWrap] = useState(false);
9089
const [fontSize, setFontSize] = useState(14);
91-
9290
const [isImporting, setIsImporting] = useState(false);
9391
const isImportingRef = useRef(false);
9492
const fileInputRef = useRef(null);
@@ -151,11 +149,6 @@ function EditorComponent() {
151149
}
152150
};
153151

154-
const getLanguageLogoById = (id) => {
155-
const language = LANGUAGES.find((lang) => parseInt(lang.ID, 10) === parseInt(id, 10));
156-
return language ? language.LOGO : null;
157-
};
158-
159152
const submitCode = useCallback(async () => {
160153
if (!editorRef.current) {
161154
enqueueSnackbar("Editor not ready", { variant: "error" });
@@ -176,6 +169,7 @@ function EditorComponent() {
176169

177170
try {
178171
const encodedCode = btoa(codeToSubmit);
172+
179173
const response = await fetch(
180174
`${judge0SubmitUrl}?base64_encoded=true&wait=false&fields=*`,
181175
{
@@ -261,65 +255,199 @@ function EditorComponent() {
261255
}
262256
}, [enqueueSnackbar, languageDetails]);
263257

264-
// --- START: KEYBOARD SHORTCUT HANDLER ---
265-
useEffect(() => {
266-
const handleKeyDown = (e) => {
267-
if (!editorRef.current) return;
258+
const handleFileImport = (e) => {
259+
const file = e.target.files?.[0];
260+
if (!file) return;
268261

269-
const isMac = navigator.platform.toUpperCase().indexOf("MAC") >= 0;
270-
const ctrlKey = isMac ? e.metaKey : e.ctrlKey;
262+
setCode("");
263+
if (fileInputRef.current) fileInputRef.current.value = "";
271264

272-
// Ctrl+S → Export file
273-
if (ctrlKey && e.key === "s") {
274-
e.preventDefault();
275-
exportFile();
276-
}
277-
// Ctrl+O → Import file
278-
else if (ctrlKey && e.key === "o") {
279-
e.preventDefault();
280-
fileInputRef.current?.click();
281-
}
282-
// Ctrl+L → Clear output
283-
else if (ctrlKey && e.key.toLowerCase() === "l") {
284-
e.preventDefault();
285-
clearOutput();
286-
}
287-
// Ctrl+C → Copy output
288-
else if (ctrlKey && e.key.toLowerCase() === "c") {
289-
e.preventDefault();
290-
copyOutput();
291-
}
292-
// Ctrl+/ → Toggle line numbers
293-
else if (ctrlKey && e.key === "/") {
294-
e.preventDefault();
295-
setShowLineNumbers((prev) => !prev);
296-
}
297-
// Ctrl+Shift+W → Toggle word wrap
298-
else if (ctrlKey && e.shiftKey && e.key.toLowerCase() === "w") {
299-
e.preventDefault();
300-
setWordWrap((prev) => !prev);
265+
isImportingRef.current = true;
266+
setIsImporting(true);
267+
268+
const extension = file.name.split(".").pop().toLowerCase();
269+
const languageMap = { js: "Javascript", jsx: "Javascript", ts: "Typescript", py: "Python3", cpp: "C++", c: "C", java: "Java" };
270+
const languageName = languageMap[extension];
271+
const selectedLanguage = LANGUAGES.find((lang) => lang.NAME === languageName);
272+
273+
if (!selectedLanguage) {
274+
enqueueSnackbar("Unsupported file type", { variant: "error" });
275+
isImportingRef.current = false;
276+
setIsImporting(false);
277+
return;
278+
}
279+
280+
const reader = new FileReader();
281+
reader.onload = (event) => {
282+
setCurrentLanguage(selectedLanguage.DEFAULT_LANGUAGE);
283+
setLanguageDetails({
284+
ID: selectedLanguage.ID,
285+
NAME: selectedLanguage.NAME,
286+
DEFAULT_LANGUAGE: selectedLanguage.DEFAULT_LANGUAGE,
287+
LANGUAGE_NAME: selectedLanguage.NAME,
288+
HELLO_WORLD: selectedLanguage.HELLO_WORLD,
289+
LOGO: selectedLanguage.LOGO,
290+
});
291+
setCode(String(event.target.result ?? ""));
292+
setOutput([]);
293+
isImportingRef.current = false;
294+
setIsImporting(false);
295+
};
296+
reader.onerror = () => {
297+
enqueueSnackbar("Error reading file", { variant: "error" });
298+
isImportingRef.current = false;
299+
setIsImporting(false);
300+
};
301+
reader.readAsText(file);
302+
};
303+
304+
// ------------------- MISSING FUNCTIONS FIX -------------------
305+
const copyOutput = async () => {
306+
if (!output || output.length === 0) {
307+
enqueueSnackbar("No output to copy", { variant: "warning" });
308+
return;
309+
}
310+
const outputText = Array.isArray(output) ? output.join("\n") : String(output);
311+
try {
312+
await navigator.clipboard.writeText(outputText);
313+
enqueueSnackbar("Output copied to clipboard!", { variant: "success" });
314+
} catch {
315+
enqueueSnackbar("Failed to copy output", { variant: "error" });
316+
}
317+
};
318+
319+
const clearOutput = () => {
320+
setOutput([]);
321+
enqueueSnackbar("Output cleared", { variant: "info" });
322+
};
323+
324+
const exportFile = () => {
325+
if (!code || code.length === 0) {
326+
enqueueSnackbar("No code to export", { variant: "warning" });
327+
return;
328+
}
329+
330+
const extensionMap = { javascript: "js", javascriptreact: "js", typescript: "ts", python: "py", cpp: "cpp", c: "c", java: "java" };
331+
const langKey = (languageDetails?.DEFAULT_LANGUAGE || "").toLowerCase();
332+
const extension = extensionMap[langKey] || "txt";
333+
334+
const blob = new Blob([code], { type: "text/plain" });
335+
const url = URL.createObjectURL(blob);
336+
const link = document.createElement("a");
337+
link.href = url;
338+
link.download = `code.${extension}`;
339+
document.body.appendChild(link);
340+
link.click();
341+
document.body.removeChild(link);
342+
URL.revokeObjectURL(url);
343+
};
344+
// --------------------------------------------------------------
345+
346+
const handleEditorDidMount = useCallback(
347+
(editor, monaco) => {
348+
editorRef.current = editor;
349+
monacoRef.current = monaco;
350+
351+
try {
352+
editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter, () => {
353+
submitCode();
354+
});
355+
} catch (err) {
356+
if (process.env.NODE_ENV !== "production") console.error("Failed to register command:", err);
301357
}
302-
// Ctrl+Enter → Run code
303-
else if (ctrlKey && e.key === "Enter") {
304-
e.preventDefault();
358+
},
359+
[submitCode]
360+
);
361+
362+
useEffect(() => {
363+
const handleKeyDown = (event) => {
364+
if ((event.ctrlKey || event.metaKey) && event.key === "Enter") {
365+
event.preventDefault();
305366
submitCode();
306367
}
307368
};
308-
309369
document.addEventListener("keydown", handleKeyDown);
310370
return () => document.removeEventListener("keydown", handleKeyDown);
311-
}, [exportFile, fileInputRef, clearOutput, copyOutput, submitCode]);
312-
// --- END: KEYBOARD SHORTCUT HANDLER ---
371+
}, [submitCode]);
313372

314-
// (All your existing EditorComponent code remains unchanged after this point)
373+
useEffect(() => {
374+
return () => {
375+
if (timeoutRef.current) {
376+
clearTimeout(timeoutRef.current);
377+
timeoutRef.current = null;
378+
}
379+
};
380+
}, []);
381+
382+
function handleLanguageChange(_, value) {
383+
if (isImporting) return;
384+
setCurrentLanguage(value.DEFAULT_LANGUAGE);
385+
setOutput([]);
386+
setCode((prev) => (prev ? prev : value.HELLO_WORLD || ""));
387+
}
315388

316-
// For brevity: existing Editor rendering, import/export buttons, output area, settings, and footer remain unchanged
389+
const handleSignOut = async () => {
390+
try {
391+
await logOut();
392+
} catch (error) {
393+
if (process.env.NODE_ENV !== "production") console.error("Sign out error:", error);
394+
}
395+
};
396+
397+
const handleLineNumbersToggle = (event) => setShowLineNumbers(event.target.checked);
398+
const handleWordWrapToggle = (event) => setWordWrap(event.target.checked);
399+
const handleFontSizeChange = (event, newValue) => setFontSize(newValue);
400+
401+
// ------------------- JSX RENDER -------------------
402+
const renderAuthenticatedContent = () => (
403+
<>
404+
{/* Editor + Sidebar */}
405+
<StyledLayout>
406+
<Editor
407+
className="editor"
408+
theme={currentEditorTheme.NAME}
409+
onMount={handleEditorDidMount}
410+
value={code}
411+
onChange={(value) => setCode(value ?? "")}
412+
language={languageDetails.DEFAULT_LANGUAGE}
413+
options={{ minimap: { enabled: false }, lineNumbers: showLineNumbers ? "on" : "off", wordWrap: wordWrap ? "on" : "off", fontSize }}
414+
/>
415+
<div className="sidebar">
416+
{/* Import / Export */}
417+
<div style={{ display: "flex", gap: "0.5rem" }}>
418+
<StyledButton onClick={() => fileInputRef.current.click()} disabled={isImporting}>
419+
{isImporting ? <CircularProgress size={16} /> : <><FaFileUpload /> Import</>}
420+
</StyledButton>
421+
<input type="file" ref={fileInputRef} style={{ display: "none" }} accept=".java,.js,.jsx,.ts,.py,.cpp,.c" onChange={handleFileImport} />
422+
<StyledButton onClick={exportFile}>
423+
{isDownloading ? <CircularProgress size={16} /> : <><FaFileDownload /> Export</>}
424+
</StyledButton>
425+
</div>
426+
{/* Run, Copy, Clear */}
427+
<div style={{ display: "flex", gap: "0.5rem", marginTop: "1rem" }}>
428+
<StyledButton onClick={submitCode}><FaPlay /> Run</StyledButton>
429+
<StyledButton onClick={copyOutput}><FaCopy /> Copy Output</StyledButton>
430+
<StyledButton onClick={clearOutput}><FaTrash /> Clear Output</StyledButton>
431+
</div>
432+
{/* Output */}
433+
<OutputLayout>
434+
<pre>{output && output.length ? output.join("\n") : "Output will appear here..."}</pre>
435+
</OutputLayout>
436+
</div>
437+
</StyledLayout>
438+
</>
439+
);
317440

318441
return (
319-
<div className="editor-container">
320-
{/* existing JSX remains */}
321-
{/* ... */}
322-
</div>
442+
<Box sx={{ flexGrow: 1 }}>
443+
{currentUser ? renderAuthenticatedContent() : (
444+
<div>
445+
<GithubSignIn />
446+
<GoogleSignIn />
447+
</div>
448+
)}
449+
<Footer />
450+
</Box>
323451
);
324452
}
325453

0 commit comments

Comments
 (0)