commit d6df9f205a1546c205272156bd122db2c72ac42c Author: przeq piciel Date: Fri Aug 23 19:17:13 2024 +0000 first commit diff --git a/app/.eslintrc.json b/app/.eslintrc.json new file mode 100644 index 0000000..bffb357 --- /dev/null +++ b/app/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "next/core-web-vitals" +} diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..fd3dbb5 --- /dev/null +++ b/app/.gitignore @@ -0,0 +1,36 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js +.yarn/install-state.gz + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/app/README.md b/app/README.md new file mode 100644 index 0000000..c403366 --- /dev/null +++ b/app/README.md @@ -0,0 +1,36 @@ +This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). + +## Getting Started + +First, run the development server: + +```bash +npm run dev +# or +yarn dev +# or +pnpm dev +# or +bun dev +``` + +Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. + +You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. + +This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. + +## Learn More + +To learn more about Next.js, take a look at the following resources: + +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. +- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. + +You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! + +## Deploy on Vercel + +The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. + +Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. diff --git a/app/app/console/page.tsx b/app/app/console/page.tsx new file mode 100644 index 0000000..5f8bc96 --- /dev/null +++ b/app/app/console/page.tsx @@ -0,0 +1,14 @@ +import Console from "@/components/WebConsole"; +import Chat from "@/components/Chat"; + +export default function Page() { + const url = + "wss://wings01.przeqpiciel.com:8081/api/servers/0bf192ab-04b7-4f0d-8535-e412565a5102/ws"; + const token = + "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImp0aSI6IjBmMmUzMmQyNjFkOWYzYjRjNWZiZDZhZWY2OTQxZDA2In0.eyJpc3MiOiJodHRwczovL3B0ZXJvLnByemVxcGljaWVsLmNvbSIsImF1ZCI6WyJodHRwczovL3dpbmdzMDEucHJ6ZXFwaWNpZWwuY29tOjgwODEiXSwianRpIjoiMGYyZTMyZDI2MWQ5ZjNiNGM1ZmJkNmFlZjY5NDFkMDYiLCJpYXQiOjE3MjQyNzQ3MjEsIm5iZiI6MTcyNDI3NDQyMSwiZXhwIjoxNzI0Mjc1MzIxLCJzZXJ2ZXJfdXVpZCI6IjBiZjE5MmFiLTA0YjctNGYwZC04NTM1LWU0MTI1NjVhNTEwMiIsInBlcm1pc3Npb25zIjpbIioiLCJhZG1pbi53ZWJzb2NrZXQuZXJyb3JzIiwiYWRtaW4ud2Vic29ja2V0Lmluc3RhbGwiLCJhZG1pbi53ZWJzb2NrZXQudHJhbnNmZXIiXSwidXNlcl91dWlkIjoiYzVmMjJiZjMtOTc1Zi00NDNlLWJiNDAtZDYwMGRhN2JkOTUzIiwidXNlcl9pZCI6MSwidW5pcXVlX2lkIjoidzEybms1QXpaZEdGY1V5QiJ9.LS_DS5Zy6NFVY0Wsob7QbRHat7_AHJ3ag6yfTmHzRWQ"; + return ( +
+ +
+ ); +} diff --git a/app/app/favicon.ico b/app/app/favicon.ico new file mode 100644 index 0000000..718d6fe Binary files /dev/null and b/app/app/favicon.ico differ diff --git a/app/app/globals.css b/app/app/globals.css new file mode 100644 index 0000000..875c01e --- /dev/null +++ b/app/app/globals.css @@ -0,0 +1,33 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +:root { + --foreground-rgb: 0, 0, 0; + --background-start-rgb: 214, 219, 220; + --background-end-rgb: 255, 255, 255; +} + +@media (prefers-color-scheme: dark) { + :root { + --foreground-rgb: 255, 255, 255; + --background-start-rgb: 0, 0, 0; + --background-end-rgb: 0, 0, 0; + } +} + +body { + color: rgb(var(--foreground-rgb)); + background: linear-gradient( + to bottom, + transparent, + rgb(var(--background-end-rgb)) + ) + rgb(var(--background-start-rgb)); +} + +@layer utilities { + .text-balance { + text-wrap: balance; + } +} diff --git a/app/app/layout.tsx b/app/app/layout.tsx new file mode 100644 index 0000000..30285c9 --- /dev/null +++ b/app/app/layout.tsx @@ -0,0 +1,24 @@ +import type { Metadata } from "next"; +import { Inter } from "next/font/google"; +import "./globals.css"; + +const inter = Inter({ subsets: ["latin"] }); + +export const metadata: Metadata = { + title: "Create Next App", + description: "Generated by create next app", +}; + +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + + +
{children}
+ + + ); +} diff --git a/app/app/page.tsx b/app/app/page.tsx new file mode 100644 index 0000000..5705d4e --- /dev/null +++ b/app/app/page.tsx @@ -0,0 +1,113 @@ +import Image from "next/image"; + +export default function Home() { + return ( +
+
+

+ Get started by editing  + app/page.tsx +

+
+ + By{" "} + Vercel Logo + +
+
+ +
+ Next.js Logo +
+ +
+ +

+ Docs{" "} + + -> + +

+

+ Find in-depth information about Next.js features and API. +

+
+ + +

+ Learn{" "} + + -> + +

+

+ Learn about Next.js in an interactive course with quizzes! +

+
+ + +

+ Templates{" "} + + -> + +

+

+ Explore starter templates for Next.js. +

+
+ + +

+ Deploy{" "} + + -> + +

+

+ Instantly deploy your Next.js site to a shareable URL with Vercel. +

+
+
+
+ ); +} diff --git a/app/app/test/page.tsx b/app/app/test/page.tsx new file mode 100644 index 0000000..5649bcf --- /dev/null +++ b/app/app/test/page.tsx @@ -0,0 +1,11 @@ +import Header from "@/components/Header" + +export default function Page() { + return ( +
+
+
+ Main page test +
+ ) +} \ No newline at end of file diff --git a/app/components/Chat/index.tsx b/app/components/Chat/index.tsx new file mode 100644 index 0000000..2a046f3 --- /dev/null +++ b/app/components/Chat/index.tsx @@ -0,0 +1,19 @@ +import React from "react"; + +const index = () => { + return ( +
+
+
+ ChitChat Logo +
+
+
ChitChat
+

You have a new message!

+
+
+
+ ); +}; + +export default index; diff --git a/app/components/Header/Logo.tsx b/app/components/Header/Logo.tsx new file mode 100644 index 0000000..054f465 --- /dev/null +++ b/app/components/Header/Logo.tsx @@ -0,0 +1,7 @@ +"use client"; + +export default function Logo() { + return ( +
Logo
+ ); +} \ No newline at end of file diff --git a/app/components/Header/Menu.tsx b/app/components/Header/Menu.tsx new file mode 100644 index 0000000..94916cc --- /dev/null +++ b/app/components/Header/Menu.tsx @@ -0,0 +1,10 @@ +"use client"; + +export default function Menu({name} : any) { + return ( +
+ {name} +
Menu
+
+ ); +} \ No newline at end of file diff --git a/app/components/Header/index.tsx b/app/components/Header/index.tsx new file mode 100644 index 0000000..56d88d3 --- /dev/null +++ b/app/components/Header/index.tsx @@ -0,0 +1,17 @@ +"use client"; + +import Logo from '@/components/Header/Logo'; +import Menu from '@/components/Header/Menu'; + + + +export default function Header(props: any) { + return ( +
+ {props.name} {props.age} {props.isMan ? 'is a man' : 'is a woman'} + +
Header item
+ +
+ ); +} \ No newline at end of file diff --git a/app/components/WebConsole/index.tsx b/app/components/WebConsole/index.tsx new file mode 100644 index 0000000..e7e0119 --- /dev/null +++ b/app/components/WebConsole/index.tsx @@ -0,0 +1,173 @@ +"use client"; + +import React, { useEffect, useState, useRef } from "react"; +import Stats from "./stats"; + +const Console = () => { + const [url, setUrl] = useState(""); + const [token, setToken] = useState(""); + const [output, setOutput] = useState([]); + const [input, setInput] = useState(""); + const [cpuStat, setCpuStat] = useState(0); + const [ramStat, setRamStat] = useState(0); + const [ramTotal, setRamTotal] = useState(0); + const [diskUsage, setDiskUsage] = useState(0); + const [diskTotal, setDiskTotal] = useState(0); + const [network, setNetwork] = useState({ inbound: 0, outbound: 0 }); + const [uptime, setUptime] = useState(0); + + const websocketRef = useRef(null); // Dodajemy ref do WebSocket + const textareaRef = useRef(null); // Dodajemy referencję do textarea + + const fetchData = async () => { + try { + const response = await fetch( + "https://ptero.przeqpiciel.com/api/client/servers/0bf192ab/websocket", + { + method: "GET", + headers: { + Authorization: + "Bearer ptlc_aDGU4VHNQuN5t6dyxNzVon3UZLR5ehuySmdR7xsUbMm", + "Content-Type": "application/json", + }, + } + ); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + const data = await response.json(); + setUrl(data.data.socket); + setToken(data.data.token); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + const fetchStats = async () => { + setDiskTotal(5); + }; + + useEffect(() => { + fetchData(); + fetchStats(); + }, []); + + useEffect(() => { + if (url && token) { + const websocket = new WebSocket(url); + websocketRef.current = websocket; + + websocket.onopen = () => { + console.log("WebSocket connection established."); + websocket.send(`{"event":"auth","args":["${token}"]}`); + }; + + websocket.onmessage = (event) => { + const message = JSON.parse(event.data); + // console.log("Received message:", message.event); + + if (message.event === "token expiring") { + fetchData(); + websocket.send(`{"event":"auth","args":["${token}"]}`); + console.log("New token fetched"); + } + + if (message.event === "stats") { + let data = JSON.parse(JSON.parse(event.data).args[0]); + setCpuStat(data.cpu_absolute.toFixed(2)); + setRamStat( + Number((data.memory_bytes / (1024 * 1024 * 1024)).toFixed(2)) + ); + setRamTotal( + Number((data.memory_limit_bytes / (1024 * 1024 * 1024)).toFixed(2)) + ); + setDiskUsage( + Number((data.disk_bytes / (1024 * 1024 * 1024)).toFixed(2)) + ); + setNetwork({ + inbound: data.network.rx_bytes, + outbound: data.network.tx_bytes, + }); + setUptime(data.uptime); + } + + if (message.event === "console output") { + setOutput((prevOutput) => { + let tmpMessage = JSON.parse(event.data).args[0]; + tmpMessage = tmpMessage.replace(/\u001b\[[0-9;]*m/g, ""); + const newOutput = [...prevOutput, tmpMessage]; + if (newOutput.length > 1000) { + return newOutput.slice(-1000); + } + return newOutput; + }); + } + }; + + websocket.onclose = () => { + console.log("WebSocket connection closed."); + }; + + websocket.onerror = (error) => { + console.error("WebSocket error:", error); + }; + + return () => { + websocket.close(); + }; + } + }, [url, token]); + + useEffect(() => { + if (textareaRef.current) { + textareaRef.current.scrollTop = textareaRef.current.scrollHeight; + } + }, [output]); + + const handleKeyPress = (e: React.KeyboardEvent) => { + if (e.key === "Enter" && websocketRef.current) { + console.log("Sending message:", input); + websocketRef.current.send(`{"event":"send command","args":["${input}"]}`); + setInput(""); + } + }; + + return ( +
+
+
+