From 1690169d5aa7244702b455b8f4307c96819e5b50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=B8=D1=82=D0=B0=D0=BB=D0=B8=D0=B9=20=D0=9B=D0=B0?= =?UTF-8?q?=D0=B2=D1=88=D0=BE=D0=BD=D0=BE=D0=BA?= <114582703+valavshonok@users.noreply.github.com> Date: Mon, 27 Oct 2025 13:24:01 +0300 Subject: [PATCH] Add editor lang --- src/App.tsx | 2 +- src/assets/icons/input/receipt.png | Bin 0 -> 9119 bytes .../drop-down-list/DropDownList.tsx | 52 ++++++++++++------ src/hooks/useClickOutside.ts | 18 ++++++ src/views/problem/codeeditor/CodeEditor.tsx | 8 ++- src/views/problem/statement/Statement.tsx | 0 6 files changed, 59 insertions(+), 21 deletions(-) create mode 100644 src/assets/icons/input/receipt.png create mode 100644 src/hooks/useClickOutside.ts create mode 100644 src/views/problem/statement/Statement.tsx diff --git a/src/App.tsx b/src/App.tsx index 2b2668e..9982d81 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -12,7 +12,7 @@ function App() {
}/> -
}/> + }/> }/> diff --git a/src/assets/icons/input/receipt.png b/src/assets/icons/input/receipt.png new file mode 100644 index 0000000000000000000000000000000000000000..0f7c554986a50bf98d329ac608e13aba63a47ccf GIT binary patch literal 9119 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 void; defaultState?: DropDownListItem; items: DropDownListItem[]; @@ -20,52 +21,67 @@ export const DropDownList: React.FC = ({ className = "", onChange, defaultState, - items = [{text: "", value: ""}], + items = [{ text: "", value: "" }], }) => { if (items.length == 0) - items.push({text: "", value: ""}); + items.push({ text: "", value: "" }); const [value, setValue] = React.useState(defaultState != undefined ? defaultState : items[0]); const [active, setActive] = React.useState(false); React.useEffect(() => onChange(value.value), [value]); + const ref = React.useRef(null); + + useClickOutside(ref, () => { + setActive(false); + }); + + return (
+ )} + ref={ref} + >
setActive(!active)}> + onClick={() => { + setActive(!active); + } + }> {value.text}
+ className={cn(" absolute right-[16px] h-[24px] w-[24px] top-[8.5px] rotate-0 transition-all duration-300 pointer-events-none", + active && " rotate-180" + )} /> -
+
{items.map((v, i) =>
{ setValue(v); @@ -73,8 +89,8 @@ export const DropDownList: React.FC = ({ }}> {v.text} - {v.text == value.text && - + {v.text == value.text && + }
)} diff --git a/src/hooks/useClickOutside.ts b/src/hooks/useClickOutside.ts new file mode 100644 index 0000000..fb27289 --- /dev/null +++ b/src/hooks/useClickOutside.ts @@ -0,0 +1,18 @@ +import React from "react"; + +export const useClickOutside = (ref: React.RefObject, onClickOutside: () => void) => { + React.useEffect(() => { + const handleClickOutside = (event: MouseEvent | TouchEvent) => { + if (ref.current && !ref.current.contains(event.target)) { + onClickOutside(); + } + } + + document.addEventListener("mousedown", handleClickOutside); + document.addEventListener("touchstart", handleClickOutside); + return () => { + document.removeEventListener("mousedown", handleClickOutside); + document.removeEventListener("touchstart", handleClickOutside); + } + }, [ref, onClickOutside]); +} \ No newline at end of file diff --git a/src/views/problem/codeeditor/CodeEditor.tsx b/src/views/problem/codeeditor/CodeEditor.tsx index eb53729..94974cd 100644 --- a/src/views/problem/codeeditor/CodeEditor.tsx +++ b/src/views/problem/codeeditor/CodeEditor.tsx @@ -10,6 +10,8 @@ const languageMap: Record = { java: "java", python: "python", pascal: "pascal", + kotlin: "kotlin", + csharp: "csharp" }; const CodeEditor: React.FC = () => { @@ -22,8 +24,10 @@ const CodeEditor: React.FC = () => { { value: "c", text: "C" }, { value: "cpp", text: "C++" }, { value: "java", text: "Java" }, - { value: "python", text: "Python" }, + { value: "python", text: "Python" }, { value: "pascal", text: "Pascal" }, + { value: "kotlin", text: "Kotlin" }, + { value: "csharp", text: "C#" }, ]; const handleFileUpload = (e: React.ChangeEvent) => { @@ -70,7 +74,7 @@ const CodeEditor: React.FC = () => { return (
{/* Панель выбора языка и загрузки файла */} -
+
{ setLanguage(v) }} /> diff --git a/src/views/problem/statement/Statement.tsx b/src/views/problem/statement/Statement.tsx new file mode 100644 index 0000000..e69de29