187 lines
5.1 KiB
TypeScript
187 lines
5.1 KiB
TypeScript
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
import {
|
|
Box,
|
|
Button,
|
|
LoadingOverlay,
|
|
Text,
|
|
Title,
|
|
Tooltip,
|
|
} from "@mantine/core";
|
|
import { useEffect, useRef, useState } from "react";
|
|
import io from "socket.io-client";
|
|
import { WorkingPage } from "../components/dashboard";
|
|
import { IBid, IWebBid } from "../system/type";
|
|
import { checkStatus } from "../apis/auth";
|
|
import { IconPower, IconRestore } from "@tabler/icons-react";
|
|
import { useConfirmStore } from "../lib/zustand/use-confirm";
|
|
import { getStatusTool, resetTool, shutdownTool } from "../apis/dashboard";
|
|
import { cn } from "../utils";
|
|
import { useStatusToolStore } from "../lib/zustand/use-status-tool-store";
|
|
|
|
const socket = io(`${import.meta.env.VITE_SOCKET_URL}/admin-bid-ws`, {
|
|
autoConnect: true,
|
|
transports: ["websocket"],
|
|
});
|
|
|
|
export default function DashBoard() {
|
|
const [workingData, setWorkingData] = useState<
|
|
(IWebBid & { type: string })[] | (IBid & { type: string })[]
|
|
>([]);
|
|
const { setConfirm } = useConfirmStore();
|
|
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
const { setStatusTool, statusTool } = useStatusToolStore();
|
|
|
|
const RETRY_CONNECT = useRef(2);
|
|
|
|
useEffect(() => {
|
|
socket.connect();
|
|
|
|
socket.on("connect", () => {
|
|
socket.emit("getBidsData");
|
|
});
|
|
|
|
socket.on("disconnect", async () => {
|
|
if (RETRY_CONNECT.current > 0) {
|
|
await checkStatus();
|
|
|
|
socket.connect();
|
|
|
|
RETRY_CONNECT.current--;
|
|
return;
|
|
}
|
|
});
|
|
|
|
socket.on("adminBidsUpdated", (data: IWebBid[]) => {
|
|
const array = data.reduce((prev, cur) => {
|
|
if (cur.children?.length > 0) {
|
|
prev = [...prev, ...cur.children];
|
|
}
|
|
prev.push(cur);
|
|
return prev;
|
|
}, [] as any[]);
|
|
|
|
const newData = array.map((item) => {
|
|
if (item.children) {
|
|
return {
|
|
...item,
|
|
type: "API_BID",
|
|
};
|
|
}
|
|
|
|
return {
|
|
...item,
|
|
type: "PRODUCT_TAB",
|
|
};
|
|
});
|
|
setWorkingData(newData);
|
|
});
|
|
|
|
return () => {
|
|
console.log("🔌 Cleanup WebSocket listeners...");
|
|
socket.off("adminBidsUpdated");
|
|
socket.off("working");
|
|
socket.off("connect");
|
|
socket.off("disconnect");
|
|
socket.disconnect();
|
|
};
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
const statusTool = async () => {
|
|
const result = await getStatusTool();
|
|
|
|
if (result?.data) {
|
|
setStatusTool(result?.data);
|
|
} else {
|
|
setStatusTool(false);
|
|
}
|
|
};
|
|
|
|
const intervalId = setInterval(statusTool, 5000);
|
|
|
|
return () => {
|
|
clearInterval(intervalId);
|
|
};
|
|
}, []);
|
|
|
|
const handleResetTool = () => {
|
|
setConfirm({
|
|
handleOk: async () => {
|
|
setLoading(true);
|
|
await resetTool();
|
|
setLoading(false);
|
|
},
|
|
title: "Confirm tool reset",
|
|
message:
|
|
"Are you sure you want to reset this tool? All current processes will be stopped and restarted.",
|
|
okButton: { value: "Ok", color: "blue" },
|
|
});
|
|
};
|
|
|
|
const handleShutdownTool = () => {
|
|
setConfirm({
|
|
handleOk: async () => {
|
|
setLoading(true);
|
|
await shutdownTool();
|
|
setLoading(false);
|
|
},
|
|
title: "Confirm tool shutdown",
|
|
message:
|
|
"Are you sure you want to shut down this tool? All running processes will be stopped and the tool will go offline.",
|
|
okButton: { value: "Ok", color: "blue" },
|
|
});
|
|
};
|
|
|
|
return (
|
|
<Box>
|
|
<Box className="flex items-center justify-between">
|
|
<Title order={2} mb="md">
|
|
Admin Dashboard
|
|
</Title>
|
|
|
|
<Tooltip label={typeof statusTool === "string" && statusTool}>
|
|
<Box
|
|
className={cn("flex gap-2 border py-3 px-4 rounded-md", {
|
|
["border-green-800"]: statusTool || statusTool === "online",
|
|
["border-red-800"]: !statusTool || statusTool !== "online",
|
|
})}
|
|
>
|
|
<Button
|
|
color={statusTool === "online" ? "blue" : "green"}
|
|
onClick={handleResetTool}
|
|
leftSection={<IconRestore size={16} />}
|
|
size="xs"
|
|
>
|
|
{statusTool === "online" ? "Reset tool" : "Start tool"}
|
|
</Button>
|
|
<Button
|
|
onClick={handleShutdownTool}
|
|
leftSection={<IconPower size={16} />}
|
|
color="red"
|
|
size="xs"
|
|
>
|
|
Shutdown tool
|
|
</Button>
|
|
</Box>
|
|
</Tooltip>
|
|
</Box>
|
|
<Box className="grid lg:grid-cols-3 2xl:grid-cols-4 gap-4 mt-5">
|
|
{workingData.length > 0 &&
|
|
workingData.map((item, index) => (
|
|
<WorkingPage socket={socket} data={item} key={item.id + index} />
|
|
))}
|
|
|
|
{workingData.length <= 0 && (
|
|
<Box className="flex items-center justify-center col-span-4">
|
|
<Text>No Pages</Text>
|
|
</Box>
|
|
)}
|
|
</Box>
|
|
|
|
<LoadingOverlay visible={loading} />
|
|
</Box>
|
|
);
|
|
}
|