feat: IDE
ci-front / build (push) Successful in 2m19s

This commit is contained in:
nikita
2026-04-04 04:59:42 +03:00
parent 9d1096a9b4
commit f537f1eab9
20 changed files with 2884 additions and 15 deletions
+191
View File
@@ -0,0 +1,191 @@
import React, { useEffect } from "react";
import { MdAdd } from "react-icons/md";
import { GoTrash } from "react-icons/go";
import {
useIDEStore,
initialFiles as defaultInitialFiles,
} from "./store/useIDEStore";
import type { FileNode } from "./types";
import {
FileExplorer,
TabBar,
CodeEditor,
TitleBar,
StatusBar,
} from "./components";
interface IDEProps {
initialFiles?: FileNode;
}
export const IDE: React.FC<IDEProps> = ({
initialFiles: externalFiles,
}: IDEProps = {}) => {
const files = useIDEStore((state) => state.files);
const openFiles = useIDEStore((state) => state.openFiles);
const activeFile = useIDEStore((state) => state.activeFile);
const createNewProject = useIDEStore((state) => state.createNewProject);
const selectFile = useIDEStore((state) => state.selectFile);
const updateFileContent = useIDEStore((state) => state.updateFileContent);
const closeFile = useIDEStore((state) => state.closeFile);
const closeAllFiles = useIDEStore((state) => state.closeAllFiles);
const closeOtherFiles = useIDEStore((state) => state.closeOtherFiles);
const initialize = useIDEStore((state) => state.initialize);
const isInitialized = useIDEStore((state) => state.isInitialized);
// Инициализация файлов
useEffect(() => {
if (!isInitialized) {
const filesToInit = externalFiles || defaultInitialFiles;
initialize(filesToInit);
}
}, [isInitialized, externalFiles, initialize]);
// Если проект не открыт
if (!files) {
return (
<div
style={{
height: "100vh",
display: "flex",
flexDirection: "column",
backgroundColor: "#1e1e1e",
fontFamily:
"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
}}
>
<TitleBar />
<div
style={{
flex: 1,
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
<div style={{ textAlign: "center" }}>
<div
style={{
marginBottom: "24px",
display: "flex",
justifyContent: "center",
opacity: 0.3,
}}
>
<GoTrash size={72} />
</div>
<div
style={{
fontSize: "22px",
marginBottom: "12px",
color: "#cccccc",
fontWeight: 300,
}}
>
No project open
</div>
<div
style={{
fontSize: "13px",
marginBottom: "32px",
color: "#858585",
}}
>
Create a new project to get started
</div>
<button
onClick={createNewProject}
style={{
padding: "10px 24px",
backgroundColor: "#0e639c",
border: "none",
borderRadius: "4px",
color: "#fff",
cursor: "pointer",
fontSize: "13px",
fontWeight: 500,
transition: "background-color 0.1s",
}}
onMouseEnter={(e) => {
e.currentTarget.style.backgroundColor = "#1177bb";
}}
onMouseLeave={(e) => {
e.currentTarget.style.backgroundColor = "#0e639c";
}}
>
<MdAdd size={14} /> New Project
</button>
</div>
</div>
<StatusBar activeFile={null} />
</div>
);
}
return (
<div
style={{
height: "100vh",
display: "flex",
flexDirection: "column",
overflow: "hidden",
backgroundColor: "#1e1e1e",
fontFamily:
"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
}}
>
<div
style={{
height: "30px",
backgroundColor: "#323233",
display: "flex",
alignItems: "center",
justifyContent: "center",
borderBottom: "1px solid #1e1e1e",
fontSize: "12px",
color: "#cccccc",
userSelect: "none",
flexShrink: 0,
}}
>
<span style={{ fontWeight: 400 }}>
{activeFile ? `${activeFile.name} - ` : ""}
{files.name}
</span>
</div>
<div style={{ display: "flex", flex: 1, overflow: "hidden" }}>
<div style={{ width: "260px", flexShrink: 0 }}>
<FileExplorer
files={files}
onDeleteRoot={useIDEStore.getState().deleteRoot}
/>
</div>
<div
style={{
flex: 1,
display: "flex",
flexDirection: "column",
overflow: "hidden",
}}
>
<TabBar
openFiles={openFiles}
activeFile={activeFile}
onSelectFile={selectFile}
onCloseFile={closeFile}
onCloseAll={closeAllFiles}
onCloseOthers={closeOtherFiles}
/>
<CodeEditor
filePath={activeFile?.path || ""}
content={activeFile?.content || ""}
onChange={updateFileContent}
/>
</div>
</div>
<StatusBar activeFile={activeFile} />
</div>
);
};
export default IDE;