Structured for prod

This commit is contained in:
2025-07-17 10:53:54 -05:00
parent 6b91411de5
commit d99281f3a7
9 changed files with 121 additions and 111 deletions
+14
View File
@@ -0,0 +1,14 @@
import Data from "../data";
export const users = new Data<{
[key: string]: { username: string; password: string };
}>("sentryx/users.json", { admin: { username: "admin", password: "admin" } });
export const sessions = new Data<{ [key: string]: string }>(
"sentryx/sessions.json",
{}
);
export default function validate(sessionId: string | null) {
return sessionId && sessions.data[sessionId] != undefined;
}
+1 -13
View File
@@ -1,15 +1,7 @@
import axios, { HttpStatusCode } from "axios"; import axios, { HttpStatusCode } from "axios";
import { NextResponse } from "next/server"; import { NextResponse } from "next/server";
import Data, { findKey } from "../data"; import Data, { findKey } from "../data";
import { sessions, users } from "./auth";
const users = new Data<{
[key: string]: { username: string; password: string };
}>("sentryx/users.json", { admin: { username: "admin", password: "admin" } });
const sessions = new Data<{ [key: string]: string }>(
"sentryx/sessions.json",
{}
);
export async function POST(request: Request) { export async function POST(request: Request) {
const body = await request.json(); const body = await request.json();
@@ -54,7 +46,3 @@ export async function GET(request: Request) {
return NextResponse.json({ message: "ok" }); return NextResponse.json({ message: "ok" });
} }
export function validate(sessionId: string | null) {
return sessionId && sessions.data[sessionId] != undefined;
}
+2 -2
View File
@@ -1,7 +1,7 @@
import { HttpStatusCode } from "axios"; import { HttpStatusCode } from "axios";
import { NextResponse } from "next/server"; import { NextResponse } from "next/server";
import { servers } from "../servers/route"; import { servers } from "../servers/servers";
import { validate } from "../auth/route"; import validate from "../auth/auth";
/* /*
Vision: This will be Vision: This will be
+2 -50
View File
@@ -2,56 +2,8 @@ import { NextResponse } from "next/server";
import Data from "../data"; import Data from "../data";
import Server, { ServerAPI } from "@/types/server"; import Server, { ServerAPI } from "@/types/server";
import { HttpStatusCode } from "axios"; import { HttpStatusCode } from "axios";
import { validate } from "../auth/route"; import validate from "../auth/auth";
import { currentServers, deletes, servers, useServer } from "./servers";
const useServer = (server: ServerAPI, index: number) => {
const ws = new WebSocket(`ws://${server.ip}:5273`);
ws.onmessage = (msg) => {
try {
if (deletes.has(index) || !currentServers[index]) {
ws.close();
return;
}
if (msg.data === "Success") {return}
const data = JSON.parse(msg.data);
if (data.status) {
currentServers[index].status = data.status;
}
if (data.cpu) {
currentServers[index].cpu = data.cpu;
}
if (data.memory) {
currentServers[index].memory = data.memory;
}
if (data.disk) {
currentServers[index].storage = data.disk;
}
if (data.network) {
currentServers[index].network = data.network;
}
} catch (e) {
console.error("Error parsing WebSocket message:", e);
}
};
ws.onopen = () => ws.send("my-key");
};
const deletes = new Set<number>();
export const servers = new Data<ServerAPI[]>("sentryx/servers.json", []);
export var currentServers: Server[] = servers.data.map(
(s) =>
({
...s,
status: "offline",
cpu: 0,
memory: 0,
storage: 0,
network: 0,
} as Server)
);
servers.data.map(useServer);
export async function GET(request: Request) { export async function GET(request: Request) {
const { searchParams } = new URL(request.url); const { searchParams } = new URL(request.url);
+51
View File
@@ -0,0 +1,51 @@
import Server, { ServerAPI } from "@/types/server";
import Data from "../data";
export const useServer = (server: ServerAPI, index: number) => {
const ws = new WebSocket(`ws://${server.ip}:5273`);
ws.onmessage = (msg) => {
try {
if (deletes.has(index) || !currentServers[index]) {
ws.close();
return;
}
if (msg.data === "Success") {return}
const data = JSON.parse(msg.data);
if (data.status) {
currentServers[index].status = data.status;
}
if (data.cpu) {
currentServers[index].cpu = data.cpu;
}
if (data.memory) {
currentServers[index].memory = data.memory;
}
if (data.disk) {
currentServers[index].storage = data.disk;
}
if (data.network) {
currentServers[index].network = data.network;
}
} catch (e) {
console.error("Error parsing WebSocket message:", e);
}
};
ws.onopen = () => ws.send("my-key");
};
export const deletes = new Set<number>();
export const servers = new Data<ServerAPI[]>("sentryx/servers.json", []);
export var currentServers: Server[] = servers.data.map(
(s) =>
({
...s,
status: "offline",
cpu: 0,
memory: 0,
storage: 0,
network: 0,
} as Server)
);
servers.data.map(useServer);
+20
View File
@@ -0,0 +1,20 @@
import { Label } from "@/components/ui/label";
import { Progress } from "@/components/ui/progress";
export default function Summary({
value,
children,
}: {
value: number;
children: React.ReactNode;
}) {
return (
<div className="flex flex-col gap-2 w-full">
<div className="justify-between flex">
<Label className="text-md">{children}</Label>
<Label className="text-md">{value}%</Label>
</div>
<Progress value={value} />
</div>
);
}
+26
View File
@@ -0,0 +1,26 @@
import { Card } from "@/components/ui/card";
import { Label } from "@/components/ui/label";
import { cn } from "@/lib/utils";
export default function SummaryCard({
children,
value,
icon,
className,
}: {
children: React.ReactNode;
value: string;
icon: React.ElementType;
className?: string;
}) {
const Icon = icon;
return (
<Card className="h-24 flex flex-row justify-between items-center gap-0 px-6">
<div className="">
<Label className="text-md font-bold text-foreground">{children}</Label>
<Label className={cn("text-2xl font-bold", className)}>{value}</Label>
</div>
<Icon className={cn("shrink-0", className)} size={32} />
</Card>
);
}
+5 -45
View File
@@ -13,61 +13,20 @@ import { Button } from "@/components/ui/button";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import useSession from "@/hooks/useSession"; import useSession from "@/hooks/useSession";
import Server from "@/types/server"; import Server from "@/types/server";
import { toast } from "sonner"; import SummaryCard from "./SummaryCard";
export function generateHourlyData() { function generateHourlyData() {
const result = []; const result = [];
for (let hour = 24; hour >= 0; hour--) { for (let hour = 24; hour >= 0; hour--) {
result.push({ result.push({
hour: hour, hour: hour,
cpu: Math.floor(Math.random() * 20 + 30), // random CPU usage between 0-99 cpu: Math.floor(Math.random() * 20 + 30),
ram: Math.floor(Math.random() * 40 + 40), // random RAM usage between 0-99 ram: Math.floor(Math.random() * 40 + 40),
}); });
} }
return result; return result;
} }
export function SummaryCard({
children,
value,
icon,
className,
}: {
children: React.ReactNode;
value: string;
icon: React.ElementType;
className?: string;
}) {
const Icon = icon;
return (
<Card className="h-24 flex flex-row justify-between items-center gap-0 px-6">
<div className="">
<Label className="text-md font-bold text-foreground">{children}</Label>
<Label className={cn("text-2xl font-bold", className)}>{value}</Label>
</div>
<Icon className={cn("shrink-0", className)} size={32} />
</Card>
);
}
export function Summary({
value,
children,
}: {
value: number;
children: React.ReactNode;
}) {
return (
<div className="flex flex-col gap-2 w-full">
<div className="justify-between flex">
<Label className="text-md">{children}</Label>
<Label className="text-md">{value}%</Label>
</div>
<Progress value={value} />
</div>
);
}
function average<T>(values: Array<T>, p: (v: T) => number) { function average<T>(values: Array<T>, p: (v: T) => number) {
return values.length > 0 return values.length > 0
? values.reduce((sum, value) => sum + p(value), 0) / values.length ? values.reduce((sum, value) => sum + p(value), 0) / values.length
@@ -115,6 +74,7 @@ export default function Dashboard() {
}; };
useEffect(() => { useEffect(() => {
getServers();
const interval = setInterval(() => { const interval = setInterval(() => {
console.log("Refreshing servers data..."); console.log("Refreshing servers data...");
getServers(); getServers();
-1
View File
@@ -9,7 +9,6 @@ import Server from "@/types/server";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import Map from "./Map"; import Map from "./Map";
import NewServerDialog from "./NewServerDialog"; import NewServerDialog from "./NewServerDialog";
import { toast } from "sonner";
export default function Servers() { export default function Servers() {
const session = useSession(); const session = useSession();