formatting
This commit is contained in:
@@ -1,141 +1,153 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import Editor from "@monaco-editor/react";
|
||||
import { upload } from "../../../assets/icons/input";
|
||||
import { cn } from "../../../lib/cn";
|
||||
import { DropDownList } from "../../../components/drop-down-list/DropDownList";
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import Editor from '@monaco-editor/react';
|
||||
import { upload } from '../../../assets/icons/input';
|
||||
import { cn } from '../../../lib/cn';
|
||||
import { DropDownList } from '../../../components/drop-down-list/DropDownList';
|
||||
|
||||
const languageMap: Record<string, string> = {
|
||||
c: "cpp",
|
||||
"C++": "cpp",
|
||||
java: "java",
|
||||
python: "python",
|
||||
pascal: "pascal",
|
||||
kotlin: "kotlin",
|
||||
csharp: "csharp"
|
||||
c: 'cpp',
|
||||
'C++': 'cpp',
|
||||
java: 'java',
|
||||
python: 'python',
|
||||
pascal: 'pascal',
|
||||
kotlin: 'kotlin',
|
||||
csharp: 'csharp',
|
||||
};
|
||||
|
||||
export interface CodeEditorProps {
|
||||
export interface CodeEditorProps {
|
||||
onChange: (value: string) => void;
|
||||
onChangeLanguage: (value: string) => void;
|
||||
}
|
||||
|
||||
const CodeEditor: React.FC<CodeEditorProps> = ({onChange, onChangeLanguage}) => {
|
||||
const [language, setLanguage] = useState<string>("C++");
|
||||
const [code, setCode] = useState<string>("");
|
||||
const [isDragging, setIsDragging] = useState<boolean>(false);
|
||||
const CodeEditor: React.FC<CodeEditorProps> = ({
|
||||
onChange,
|
||||
onChangeLanguage,
|
||||
}) => {
|
||||
const [language, setLanguage] = useState<string>('C++');
|
||||
const [code, setCode] = useState<string>('');
|
||||
const [isDragging, setIsDragging] = useState<boolean>(false);
|
||||
|
||||
const items = [
|
||||
{ value: 'c', text: 'C' },
|
||||
{ value: 'C++', text: 'C++' },
|
||||
{ value: 'java', text: 'Java' },
|
||||
{ value: 'python', text: 'Python' },
|
||||
{ value: 'pascal', text: 'Pascal' },
|
||||
{ value: 'kotlin', text: 'Kotlin' },
|
||||
{ value: 'csharp', text: 'C#' },
|
||||
];
|
||||
|
||||
const items = [
|
||||
{ value: "c", text: "C" },
|
||||
{ value: "C++", text: "C++" },
|
||||
{ value: "java", text: "Java" },
|
||||
{ value: "python", text: "Python" },
|
||||
{ value: "pascal", text: "Pascal" },
|
||||
{ value: "kotlin", text: "Kotlin" },
|
||||
{ value: "csharp", text: "C#" },
|
||||
];
|
||||
useEffect(() => {
|
||||
onChange(code);
|
||||
}, [code]);
|
||||
useEffect(() => {
|
||||
onChangeLanguage(language);
|
||||
}, [language]);
|
||||
|
||||
useEffect(() => {
|
||||
onChange(code);
|
||||
}, [code])
|
||||
useEffect(() => {
|
||||
onChangeLanguage(language);
|
||||
}, [language])
|
||||
const handleFileUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const file = e.target.files?.[0];
|
||||
if (!file) return;
|
||||
|
||||
const handleFileUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const file = e.target.files?.[0];
|
||||
if (!file) return;
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onload = (event) => {
|
||||
const text = event.target?.result;
|
||||
if (typeof text === "string") setCode(text);
|
||||
const reader = new FileReader();
|
||||
reader.onload = (event) => {
|
||||
const text = event.target?.result;
|
||||
if (typeof text === 'string') setCode(text);
|
||||
};
|
||||
reader.readAsText(file);
|
||||
e.target.value = '';
|
||||
};
|
||||
reader.readAsText(file);
|
||||
e.target.value = "";
|
||||
};
|
||||
|
||||
const handleDrop = (e: React.DragEvent<HTMLLabelElement>) => {
|
||||
e.preventDefault();
|
||||
setIsDragging(false);
|
||||
const droppedFile = e.dataTransfer.files[0];
|
||||
if (!droppedFile) return;
|
||||
const handleDrop = (e: React.DragEvent<HTMLLabelElement>) => {
|
||||
e.preventDefault();
|
||||
setIsDragging(false);
|
||||
const droppedFile = e.dataTransfer.files[0];
|
||||
if (!droppedFile) return;
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onload = (event) => {
|
||||
const text = event.target?.result;
|
||||
if (typeof text === "string") setCode(text);
|
||||
const reader = new FileReader();
|
||||
reader.onload = (event) => {
|
||||
const text = event.target?.result;
|
||||
if (typeof text === 'string') setCode(text);
|
||||
};
|
||||
reader.readAsText(droppedFile);
|
||||
};
|
||||
reader.readAsText(droppedFile);
|
||||
};
|
||||
|
||||
const handleDragOver = (e: React.DragEvent<HTMLLabelElement>) => {
|
||||
e.preventDefault(); // обязательно
|
||||
};
|
||||
const handleDragOver = (e: React.DragEvent<HTMLLabelElement>) => {
|
||||
e.preventDefault(); // обязательно
|
||||
};
|
||||
|
||||
const handleDragEnter = (e: React.DragEvent<HTMLLabelElement>) => {
|
||||
e.preventDefault();
|
||||
setIsDragging(true);
|
||||
};
|
||||
const handleDragEnter = (e: React.DragEvent<HTMLLabelElement>) => {
|
||||
e.preventDefault();
|
||||
setIsDragging(true);
|
||||
};
|
||||
|
||||
const handleDragLeave = (e: React.DragEvent<HTMLLabelElement>) => {
|
||||
e.preventDefault();
|
||||
setIsDragging(false);
|
||||
};
|
||||
const handleDragLeave = (e: React.DragEvent<HTMLLabelElement>) => {
|
||||
e.preventDefault();
|
||||
setIsDragging(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex flex-col w-full h-full">
|
||||
{/* Панель выбора языка и загрузки файла */}
|
||||
<div className="flex items-center justify-between py-3 ">
|
||||
<div className="flex items-center gap-[20px]">
|
||||
<DropDownList items={items} onChange={(v) => { setLanguage(v) }} defaultState={{ value: "C++", text: "C++" }}/>
|
||||
return (
|
||||
<div className="flex flex-col w-full h-full">
|
||||
{/* Панель выбора языка и загрузки файла */}
|
||||
<div className="flex items-center justify-between py-3 ">
|
||||
<div className="flex items-center gap-[20px]">
|
||||
<DropDownList
|
||||
items={items}
|
||||
onChange={(v) => {
|
||||
setLanguage(v);
|
||||
}}
|
||||
defaultState={{ value: 'C++', text: 'C++' }}
|
||||
/>
|
||||
|
||||
<label
|
||||
className={cn("h-[40px] w-[250px] rounded-[10px] px-[16px] relative flex items-center cursor-pointer transition-all bg-liquid-lighter outline-dashed outline-[2px] outline-transparent active:scale-[95%]",
|
||||
isDragging && "outline-blue-500 "
|
||||
)}
|
||||
onDrop={handleDrop}
|
||||
onDragOver={handleDragOver}
|
||||
onDragEnter={handleDragEnter}
|
||||
onDragLeave={handleDragLeave}
|
||||
>
|
||||
<span className="text-[18px] text-liquid-white font-bold pointer-events-none">
|
||||
{"Загрузить решение"}
|
||||
</span>
|
||||
<img src={upload} className="absolute right-[16px] pointer-events-none" />
|
||||
<input
|
||||
type="file"
|
||||
onChange={(e) => handleFileUpload(e)}
|
||||
className="hidden"
|
||||
/>
|
||||
</label>
|
||||
<label
|
||||
className={cn(
|
||||
'h-[40px] w-[250px] rounded-[10px] px-[16px] relative flex items-center cursor-pointer transition-all bg-liquid-lighter outline-dashed outline-[2px] outline-transparent active:scale-[95%]',
|
||||
isDragging && 'outline-blue-500 ',
|
||||
)}
|
||||
onDrop={handleDrop}
|
||||
onDragOver={handleDragOver}
|
||||
onDragEnter={handleDragEnter}
|
||||
onDragLeave={handleDragLeave}
|
||||
>
|
||||
<span className="text-[18px] text-liquid-white font-bold pointer-events-none">
|
||||
{'Загрузить решение'}
|
||||
</span>
|
||||
<img
|
||||
src={upload}
|
||||
className="absolute right-[16px] pointer-events-none"
|
||||
/>
|
||||
<input
|
||||
type="file"
|
||||
onChange={(e) => handleFileUpload(e)}
|
||||
className="hidden"
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Monaco Editor */}
|
||||
<div className="bg-[#1E1E1E] py-[10px] h-full rounded-[10px]">
|
||||
<Editor
|
||||
width="100%"
|
||||
height="100%"
|
||||
language={languageMap[language]}
|
||||
value={code}
|
||||
onChange={(value) => setCode(value ?? '')}
|
||||
theme="vs-dark"
|
||||
options={{
|
||||
fontSize: 14,
|
||||
minimap: { enabled: false },
|
||||
automaticLayout: true,
|
||||
quickSuggestions: true,
|
||||
suggestOnTriggerCharacters: true,
|
||||
tabSize: 4,
|
||||
insertSpaces: true,
|
||||
detectIndentation: false,
|
||||
autoIndent: 'full',
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Monaco Editor */}
|
||||
<div className="bg-[#1E1E1E] py-[10px] h-full rounded-[10px]">
|
||||
<Editor
|
||||
width="100%"
|
||||
height="100%"
|
||||
language={languageMap[language]}
|
||||
value={code}
|
||||
onChange={(value) => setCode(value ?? "")}
|
||||
theme="vs-dark"
|
||||
options={{
|
||||
fontSize: 14,
|
||||
minimap: { enabled: false },
|
||||
automaticLayout: true,
|
||||
quickSuggestions: true,
|
||||
suggestOnTriggerCharacters: true,
|
||||
tabSize: 4,
|
||||
insertSpaces: true,
|
||||
detectIndentation: false,
|
||||
autoIndent: "full",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
);
|
||||
};
|
||||
|
||||
export default CodeEditor;
|
||||
|
||||
Reference in New Issue
Block a user