diff --git a/app/app/files/edit/page.tsx b/app/app/files/edit/page.tsx
index ee1b82e..6e590e4 100644
--- a/app/app/files/edit/page.tsx
+++ b/app/app/files/edit/page.tsx
@@ -23,6 +23,16 @@ function Page() {
setLanguage(event.target.value);
};
+ const saveFile = async () => {
+ const panelApp = new Panel();
+ const pterodactyl = new Pterodactyl();
+
+ const credentials = await panelApp.getCredentials();
+ pterodactyl.setApiKey(credentials.api_key);
+ pterodactyl.setServerId(serverId);
+ await pterodactyl.files.saveContent(path, code);
+ };
+
useEffect(
function () {
async function startupApp() {
@@ -82,7 +92,10 @@ function Page() {
-
diff --git a/app/app/test/page.tsx b/app/app/test/page.tsx
index 5649bcf..d770ff0 100644
--- a/app/app/test/page.tsx
+++ b/app/app/test/page.tsx
@@ -1,11 +1,27 @@
-import Header from "@/components/Header"
+"use client";
+
+import React, { useState } from "react";
+import Popup from "@/components/Popup";
export default function Page() {
- return (
-
-
-
- Main page test
-
- )
-}
\ No newline at end of file
+ const [number, addNumber] = useState(0);
+ const [showPopup, setShowPopup] = useState(true);
+
+ return (
+ <>
+ setShowPopup(false)}
+ >
+ {number}
+ addNumber(number + 1)}>
+ Add{" "}
+
+
+ setShowPopup(!showPopup)}>
+ Toggle Popup
+
+ >
+ );
+}
diff --git a/app/components/FilesEditor/AddDocument/index.tsx b/app/components/FilesEditor/AddDocument/index.tsx
new file mode 100644
index 0000000..084b17d
--- /dev/null
+++ b/app/components/FilesEditor/AddDocument/index.tsx
@@ -0,0 +1,67 @@
+"use client";
+
+import React from "react";
+import AddDocumentIcon from "@/components/Icons/AddDocument";
+import Popup from "@/components/Popup";
+import { useState } from "react";
+import Pterodactyl from "@/components/Pterodactyl";
+import { useSearchParams } from "next/navigation";
+
+const Index = () => {
+ const [showPopup, setShowPopup] = useState(false);
+ const [fileName, setFileName] = useState("");
+ const urlParams = useSearchParams();
+ const serverId = urlParams.get("serverid") || "";
+ const pathParam = urlParams.get("path") || "/";
+ const apiKey = `${process.env.NEXT_PUBLIC_API_KEY}`;
+
+ const pterodactyl = new Pterodactyl();
+
+ function togglePopup() {
+ setShowPopup(!showPopup);
+ }
+
+ function handleOk() {
+ console.log({ fileName });
+ if (fileName) {
+ pterodactyl.setApiKey(apiKey);
+ pterodactyl.setServerId(serverId);
+ pterodactyl.helpers.setWorkingDirectory(pathParam);
+ pterodactyl.files.createFile(fileName);
+ }
+ setShowPopup(false);
+ }
+
+ return (
+ <>
+
+
+ setFileName(e.target.value)}
+ />
+
+
+ {
+ setFileName("");
+ togglePopup();
+ }}
+ className="btn btn-sm"
+ >
+
+ Add Document
+
+ >
+ );
+};
+
+export default Index;
diff --git a/app/components/FilesEditor/BreadCrumbs/index.tsx b/app/components/FilesEditor/BreadCrumbs.old/index.tsx
similarity index 100%
rename from app/components/FilesEditor/BreadCrumbs/index.tsx
rename to app/components/FilesEditor/BreadCrumbs.old/index.tsx
diff --git a/app/components/FilesEditor/index.tsx b/app/components/FilesEditor/index.tsx
index 061a17c..9a8c1a7 100644
--- a/app/components/FilesEditor/index.tsx
+++ b/app/components/FilesEditor/index.tsx
@@ -11,6 +11,7 @@ import RenamePopup from "./ContextMenu/rename";
import Pterodactyl from "@/components/Pterodactyl";
import BreadCrumbs from "@/components/BreadCrumbs";
import { useSearchParams } from "next/navigation";
+import AddDocument from "./AddDocument";
interface FileAttributes {
name: string;
@@ -23,6 +24,12 @@ interface FileProps {
attributes: FileAttributes;
}
+interface NewDocumentState {
+ show: boolean;
+ x: number;
+ y: number;
+}
+
interface ContextMenuState {
show: boolean;
x: number;
@@ -34,6 +41,12 @@ interface RenamePopupState {
show: boolean;
}
+const initialNewDocumentState: NewDocumentState = {
+ show: false,
+ x: 0,
+ y: 0,
+};
+
const initialContextMenuState: ContextMenuState = {
show: false,
x: 0,
@@ -72,7 +85,6 @@ const Index = () => {
}, []);
const fetchFiles = useCallback(async () => {
- console.log("chwytam pliki");
const files = await pterodactyl.files.fetchFiles();
setFileList(files);
}, [pterodactyl]);
@@ -168,20 +180,7 @@ const Index = () => {
})}
-
- Add Document
+
diff --git a/app/components/Icons/AddDocument/index.tsx b/app/components/Icons/AddDocument/index.tsx
new file mode 100644
index 0000000..5fbbae8
--- /dev/null
+++ b/app/components/Icons/AddDocument/index.tsx
@@ -0,0 +1,25 @@
+import React from "react";
+
+const index = () => {
+ return (
+ <>
+
+ >
+ );
+};
+
+export default index;
diff --git a/app/components/Popup/index.tsx b/app/components/Popup/index.tsx
new file mode 100644
index 0000000..1b242df
--- /dev/null
+++ b/app/components/Popup/index.tsx
@@ -0,0 +1,49 @@
+"use client";
+
+import React from "react";
+
+interface PopupProps extends React.HTMLAttributes {
+ show?: boolean;
+ title?: string;
+ children: React.ReactNode;
+ onClickClose?: React.MouseEventHandler;
+ onClickOk?: React.MouseEventHandler;
+}
+
+const Popup: React.FC = ({
+ show = false,
+ title,
+ children,
+ ...props
+}) => {
+ if (!show) return null;
+
+ return (
+ <>
+
+
+
+ {title && (
+
+ {title}
+
+ )}
+ {children}
+
+
+ Close
+
+
+ Ok
+
+
+
+
+ >
+ );
+};
+
+export default Popup;
diff --git a/app/components/Pterodactyl/files.tsx b/app/components/Pterodactyl/files.tsx
index 17912bb..caf143d 100644
--- a/app/components/Pterodactyl/files.tsx
+++ b/app/components/Pterodactyl/files.tsx
@@ -77,5 +77,29 @@ export default function files(pterodactyl: any) {
console.error("Error fetching data:", error);
}
},
+
+ async saveContent(filename: string, content: string) {
+ try {
+ const response = await fetch(
+ `${process.env.NEXT_PUBLIC_URL}/api/client/servers/${pterodactyl.server_id}/files/write?file=${filename}`,
+ {
+ method: "POST",
+ headers: await pterodactyl.helpers.authHeader("application/text"),
+ body: "'test'",
+ }
+ );
+ if (!response.ok) {
+ throw new Error(`HTTP error! status: ${response.status}`);
+ }
+ const data = await response.json();
+ return data;
+ } catch (error) {
+ console.error("Error fetching data:", error);
+ }
+ },
+
+ async createFile(filename: string) {
+ this.saveContent(filename, "");
+ },
};
}
diff --git a/app/components/Pterodactyl/helpers.tsx b/app/components/Pterodactyl/helpers.tsx
index 116cb0f..6b768ac 100644
--- a/app/components/Pterodactyl/helpers.tsx
+++ b/app/components/Pterodactyl/helpers.tsx
@@ -1,10 +1,10 @@
export default function helpers(pterodactyl: any) {
return {
// helper what return auth header
- async authHeader() {
+ async authHeader(contentType: string = "application/json") {
return {
Authorization: `Bearer ${pterodactyl.api_key}`,
- "Content-Type": "application/json",
+ "Content-Type": contentType,
Accept: "Application/vnd.pterodactyl.v1+json",
};
},
@@ -28,5 +28,16 @@ export default function helpers(pterodactyl: any) {
async getWorkingDirectory() {
return pterodactyl.workingDirectory;
},
+
+ // helper that get main site and get csrf token from it
+ async getCsrfToken() {
+ const response = await fetch(`${process.env.NEXT_PUBLIC_URL}`, {
+ method: "GET",
+ });
+ const text = await response.text();
+ const match = text.match(//);
+ const csrfToken = match ? match[1] : null;
+ return csrfToken;
+ },
};
}
diff --git a/app/components/TextEditor/LanguageSelector/index.tsx b/app/components/TextEditor/LanguageSelector/index.tsx
index a3cc36e..4412ba6 100644
--- a/app/components/TextEditor/LanguageSelector/index.tsx
+++ b/app/components/TextEditor/LanguageSelector/index.tsx
@@ -31,7 +31,8 @@ const Index = (props: LanguageSelectorProps) => {
{Object.entries(languages).map(([key, value]) => (