192 lines
5.4 KiB
TypeScript
192 lines
5.4 KiB
TypeScript
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;
|