diff --git a/app/app/files/edit/page.tsx b/app/app/files/edit/page.tsx index 02158e4..7cc26f0 100644 --- a/app/app/files/edit/page.tsx +++ b/app/app/files/edit/page.tsx @@ -1,21 +1,35 @@ "use client"; -import React, { useCallback } from "react"; - +import React, { useEffect, useState } from "react"; import { useSearchParams } from "next/navigation"; import TextEditor from "@/components/TextEditor"; import BreadCrumbs from "@/components/BreadCrumbs"; import ServerIcon from "@/components/Icons/Server"; import FolderIcon from "@/components/Icons/Folder"; +import Pterodactyl from "@/components/Pterodactyl"; +import Panel from "@/components/Panel"; function Page() { const searchParams = useSearchParams(); const serverId = searchParams.get("serverid") || ""; const path = searchParams.get("path") || ""; + const [code, setCode] = useState("dupa"); + const pterodactyl = new Pterodactyl(); - const changeDirectory = useCallback((path: string) => { - console.log("changeDirectory", path); - }, []); + useEffect(() => { + const startupApp = async () => { + const panelApp = new Panel(); + + const credentials = await panelApp.getCredentials(); + pterodactyl.setApiKey(credentials.api_key); + pterodactyl.setServerId(serverId); + setCode(await pterodactyl.files.getContent(path)); + }; + + if (serverId && path) { + startupApp(); + } + }, [serverId, path]); return ( <> @@ -54,7 +68,7 @@ function Page() { ); })} - ; + ); } diff --git a/app/components/FilesEditor/index.tsx b/app/components/FilesEditor/index.tsx index 5cdcfd9..ddc1954 100644 --- a/app/components/FilesEditor/index.tsx +++ b/app/components/FilesEditor/index.tsx @@ -57,7 +57,7 @@ const Index = () => { initialRenamePopupState ); const [selectedFile, setSelectedFile] = useState(null); - const [ptero, setPtero] = useState(null); + const pterodactyl = useMemo(() => new Pterodactyl(), []); const urlParams = useSearchParams(); const serverId = urlParams.get("serverid"); const pathParam = urlParams.get("path") || "/"; @@ -71,21 +71,21 @@ const Index = () => { setRenamePopup(initialRenamePopupState); }, []); - const fetchFiles = useCallback(async (ptero: Pterodactyl) => { + const fetchFiles = useCallback(async () => { console.log("chwytam pliki"); - const files = await ptero.files.fetchFiles(); + const files = await pterodactyl.files.fetchFiles(); setFileList(files); - }, []); + }, [pterodactyl]); const handleRenameFile = useCallback( async (file: FileProps, newName: string) => { - if (ptero) { - await ptero.files.rename(file, newName); - await fetchFiles(ptero); + if (pterodactyl) { + await pterodactyl.files.rename(file, newName); + await fetchFiles(); setRenamePopup(initialRenamePopupState); } }, - [ptero, fetchFiles] + [pterodactyl, fetchFiles] ); const handleClickContextMenu = useCallback( @@ -102,29 +102,24 @@ const Index = () => { const changeDirectory = useCallback( (newPath: string) => { - if (ptero) { - ptero.helpers.setWorkingDirectory(newPath); - fetchFiles(ptero); + if (pterodactyl) { + pterodactyl.helpers.setWorkingDirectory(newPath); + fetchFiles(); // setPath(newPath); } }, - [ptero, fetchFiles] + [pterodactyl, fetchFiles] ); useEffect(() => { - const setupApplication = () => { - if (!apiKey || !serverId) return; // Upewniamy się, że mamy apiKey i serverId - if (!ptero) { - const pteroInstance = new Pterodactyl(serverId, apiKey); - setPtero(pteroInstance); + if (!apiKey || !serverId) return; // Upewniamy się, że mamy apiKey i serverId - pteroInstance.helpers.setWorkingDirectory(pathParam); - fetchFiles(pteroInstance); // Wywołanie fetchFiles raz po ustawieniu instancji - } - }; + pterodactyl.setApiKey(apiKey); + pterodactyl.setServerId(serverId); + pterodactyl.helpers.setWorkingDirectory(pathParam); - setupApplication(); - }, [apiKey, serverId, ptero, pathParam, fetchFiles]); + fetchFiles(); // Wywołanie fetchFiles raz po ustawieniu instancji + }, [apiKey, serverId, pterodactyl, pathParam, fetchFiles]); return ( <> diff --git a/app/components/Panel/index.tsx b/app/components/Panel/index.tsx new file mode 100644 index 0000000..a5daa77 --- /dev/null +++ b/app/components/Panel/index.tsx @@ -0,0 +1,16 @@ +interface Credentials { + api_key: string; +} + +class Panel { + constructor() {} + + // this method is responsible for fetching credentials from the server + async getCredentials(): Promise { + return { + api_key: `${process.env.NEXT_PUBLIC_API_KEY}`, + }; + } +} + +export default Panel; diff --git a/app/components/Pterodactyl/files.tsx b/app/components/Pterodactyl/files.tsx index de27784..17912bb 100644 --- a/app/components/Pterodactyl/files.tsx +++ b/app/components/Pterodactyl/files.tsx @@ -1,3 +1,4 @@ +import { get } from "http"; import { File } from "./interfaces"; export default function files(pterodactyl: any) { @@ -57,5 +58,24 @@ export default function files(pterodactyl: any) { console.error("Error fetching data:", error); } }, + + async getContent(filename: string) { + try { + const response = await fetch( + `${process.env.NEXT_PUBLIC_URL}/api/client/servers/${pterodactyl.server_id}/files/contents?file=${filename}`, + { + method: "GET", + headers: await pterodactyl.helpers.authHeader(), + } + ); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + const data = await response.text(); + return data; + } catch (error) { + console.error("Error fetching data:", error); + } + }, }; } diff --git a/app/components/Pterodactyl/index.tsx b/app/components/Pterodactyl/index.tsx index 9d835e1..c6d14fe 100644 --- a/app/components/Pterodactyl/index.tsx +++ b/app/components/Pterodactyl/index.tsx @@ -2,15 +2,21 @@ import filesModule from "./files"; import helpersModule from "./helpers"; class Pterodactyl { - server_id: string; - api_key: string; + server_id: string = ""; + api_key: string = ""; files: any; helpers: any; workingDirectory: string = "/"; - constructor(server_id: string, api_key: string) { - this.server_id = server_id; + setApiKey(api_key: string) { this.api_key = api_key; + } + + setServerId(server_id: string) { + this.server_id = server_id; + } + + constructor() { this.files = filesModule(this); this.helpers = helpersModule(this); } diff --git a/app/components/TextEditor/index.tsx b/app/components/TextEditor/index.tsx index 2acadf6..579ec26 100644 --- a/app/components/TextEditor/index.tsx +++ b/app/components/TextEditor/index.tsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useState, useEffect } from "react"; import MonacoEditor, { OnChange } from "@monaco-editor/react"; interface EditorProps { @@ -6,11 +6,14 @@ interface EditorProps { width?: string; theme?: string; language?: string; + code?: string; onChange?: OnChange; } const Editor = (props: EditorProps) => { - const [code, setCode] = useState('console.log("Hello, Monaco!");'); + const [code, setCode] = useState( + props.code || 'console.log("Hello, Monaco!");' + ); const handleEditorChange: OnChange = (value) => { setCode(value || ""); @@ -21,16 +24,23 @@ const Editor = (props: EditorProps) => { width = "100%", theme = "vs-dark", language = "typescript", + code: _code = code, // z props, jeśli jest dostępne onChange = handleEditorChange, } = props; + // Efekt do synchronizacji props.code z wewnętrznym stanem code + useEffect(() => { + if (_code !== undefined) { + setCode(_code); + } + }, [_code]); + return (