242 lines
7.3 KiB
JavaScript
242 lines
7.3 KiB
JavaScript
import "./App.css";
|
|
import {
|
|
Flex,
|
|
Button,
|
|
Typography,
|
|
Tag,
|
|
Menu,
|
|
ConfigProvider,
|
|
theme,
|
|
Layout,
|
|
Modal,
|
|
} from "antd";
|
|
import { MenuOutlined } from "@ant-design/icons";
|
|
import React, { useState, useEffect } from "react";
|
|
import merge from "lodash/merge";
|
|
import unionBy from "lodash/unionBy";
|
|
import Overview from "./pages/Overview";
|
|
import Printers from "./pages/Printers";
|
|
import Loading from "./pages/Loading";
|
|
import OTPInput from "./pages/OTPInput";
|
|
import CloudIcon from "./icons/CloudIcon";
|
|
import LockIcon from "./icons/LockIcon";
|
|
import SettingsIcon from "./icons/SettingsIcon";
|
|
import Disconnected from "./pages/Disconnected";
|
|
|
|
const App = () => {
|
|
const [host, setHost] = useState({});
|
|
const [printers, setPrinters] = useState([]);
|
|
const [documentPrinters, setDocumentPrinters] = useState([]);
|
|
const [connected, setConnected] = useState(false);
|
|
const [authenticated, setAuthenticated] = useState(false);
|
|
const [error, setError] = useState(null);
|
|
const [currentPageKey, setCurrentPageKey] = useState("overview");
|
|
const [loading, setLoading] = useState(true);
|
|
const [isDarkMode, setIsDarkMode] = useState(false);
|
|
|
|
// Listen for system theme changes
|
|
useEffect(() => {
|
|
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
const handleChange = (e) => {
|
|
setIsDarkMode(e.matches);
|
|
console.log("CHANGE", e);
|
|
};
|
|
mediaQuery.addEventListener("change", handleChange);
|
|
setIsDarkMode(mediaQuery.matches);
|
|
return () => mediaQuery.removeEventListener("change", handleChange);
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
console.log("Setting up IPC listeners...");
|
|
// Set up IPC listeners when component mounts
|
|
window.electronAPI.onIPCData("setHost", (newHost) => {
|
|
console.log("Host data received:", newHost);
|
|
setHost((prev) => merge(prev, newHost));
|
|
});
|
|
|
|
window.electronAPI.onIPCData("setPrinters", (newPrinters) => {
|
|
console.log("Printers data:", newPrinters);
|
|
setPrinters(newPrinters);
|
|
});
|
|
|
|
window.electronAPI.onIPCData("setPrinter", (newPrinter) => {
|
|
console.log("Printer data:", newPrinter);
|
|
setPrinters((prev) => unionBy(prev, [newPrinter], "_id"));
|
|
});
|
|
|
|
window.electronAPI.onIPCData(
|
|
"setDocumentPrinters",
|
|
(newDocumentPrinters) => {
|
|
console.log("Document printers data:", newDocumentPrinters);
|
|
setDocumentPrinters((prev) =>
|
|
unionBy(prev, newDocumentPrinters, "_id")
|
|
);
|
|
}
|
|
);
|
|
|
|
window.electronAPI.onIPCData("setAuthenticated", (setAuthenticated) => {
|
|
console.log("Set authenticated:", setAuthenticated);
|
|
setLoading(setAuthenticated);
|
|
});
|
|
|
|
window.electronAPI.onIPCData("setConnected", (isConnected) => {
|
|
console.log("Set connected:", isConnected);
|
|
setConnected(isConnected);
|
|
});
|
|
|
|
window.electronAPI.onIPCData("setAuthenticated", (isAuthenticated) => {
|
|
console.log("Set authenticated:", isAuthenticated);
|
|
setAuthenticated(isAuthenticated);
|
|
});
|
|
|
|
window.electronAPI.onIPCData("setLoading", (isLoading) => {
|
|
console.log("Set loading:", isLoading);
|
|
setLoading(isLoading);
|
|
});
|
|
|
|
window.electronAPI.onIPCData("setPrinters", (newPrinters) => {
|
|
console.log("Printers data:", newPrinters);
|
|
setPrinters((prev) => unionBy(prev, newPrinters, "_id"));
|
|
});
|
|
|
|
console.log("Sending get data...");
|
|
// Request initial data
|
|
window.electronAPI.sendIPC("getData");
|
|
|
|
// Cleanup listeners when component unmounts
|
|
return () => {
|
|
window.electronAPI.removeAllListeners("setHost");
|
|
window.electronAPI.removeAllListeners("setPrinters");
|
|
window.electronAPI.removeAllListeners("setDocumentPrinters");
|
|
window.electronAPI.removeAllListeners("setAuthenticated");
|
|
window.electronAPI.removeAllListeners("setConnected");
|
|
window.electronAPI.removeAllListeners("setLoading");
|
|
};
|
|
}, []); // Empty dependency array means this runs once on mount
|
|
|
|
// Function to render the appropriate page based on currentPageKey and auth status
|
|
const renderCurrentPage = () => {
|
|
// If loading, show loading
|
|
if (loading) {
|
|
return <Loading />;
|
|
}
|
|
|
|
// If not authenticated but connected, show OTP input
|
|
if (connected === false && loading == false) {
|
|
return <Disconnected />;
|
|
}
|
|
|
|
// If not authenticated but connected, show OTP input
|
|
if (authenticated === false && connected === true) {
|
|
return <OTPInput />;
|
|
}
|
|
|
|
// If authenticated and connected, show the selected page
|
|
switch (currentPageKey) {
|
|
case "overview":
|
|
return <Overview printers={printers} host={host} loading={loading} />;
|
|
case "printers":
|
|
return <Printers printers={printers} />;
|
|
case "documentPrinters":
|
|
return <div>Document Printers Page (to be implemented)</div>;
|
|
default:
|
|
return <Overview />;
|
|
}
|
|
};
|
|
|
|
// Handle menu item clicks
|
|
const handleMenuClick = ({ key }) => {
|
|
setCurrentPageKey(key);
|
|
};
|
|
|
|
const mainMenuItems = [
|
|
{
|
|
key: "overview",
|
|
label: "Overview",
|
|
},
|
|
{
|
|
key: "printers",
|
|
label: "Printers",
|
|
},
|
|
{
|
|
key: "documentPrinters",
|
|
label: "Document Printers",
|
|
},
|
|
];
|
|
|
|
return (
|
|
<ConfigProvider
|
|
theme={{
|
|
token: {
|
|
colorPrimary: "#007AFF",
|
|
colorSuccess: "#32D74B",
|
|
colorWarning: "#FF9F0A",
|
|
colorInfo: "#0A84FF",
|
|
colorLink: "#5AC8F5",
|
|
borderRadius: "10px",
|
|
},
|
|
components: {
|
|
Layout: {
|
|
headerBg: isDarkMode ? "#141414" : "#ffffff",
|
|
},
|
|
},
|
|
algorithm: isDarkMode ? theme.darkAlgorithm : theme.defaultAlgorithm,
|
|
}}
|
|
>
|
|
<Layout>
|
|
<Flex style={{ width: "100vw", height: "100vh" }} vertical>
|
|
<Flex
|
|
className="ant-menu-horizontal ant-menu-light"
|
|
style={{ lineHeight: "40px", padding: "0 8px 0 75px" }}
|
|
>
|
|
{loading == false && authenticated == true && connected == true ? (
|
|
<Menu
|
|
mode="horizontal"
|
|
items={mainMenuItems}
|
|
selectedKeys={[currentPageKey]}
|
|
style={{
|
|
flexWrap: "wrap",
|
|
border: 0,
|
|
lineHeight: "40px",
|
|
}}
|
|
overflowedIndicator={
|
|
<Button type="text" icon={<MenuOutlined />} />
|
|
}
|
|
onClick={handleMenuClick}
|
|
/>
|
|
) : null}
|
|
|
|
<div className="electron-navigation" style={{ flexGrow: 1 }}></div>
|
|
<Flex align="center" gap={"small"}>
|
|
<Button
|
|
type="text"
|
|
icon={<SettingsIcon />}
|
|
style={{ marginTop: "1px" }}
|
|
/>
|
|
<div>
|
|
<Tag
|
|
color={authenticated ? "success" : "warning"}
|
|
style={{ margin: 0 }}
|
|
icon={<LockIcon />}
|
|
/>
|
|
</div>
|
|
<div>
|
|
<Tag
|
|
color={connected ? "success" : "error"}
|
|
style={{ margin: 0 }}
|
|
icon={<CloudIcon />}
|
|
/>
|
|
</div>
|
|
</Flex>
|
|
</Flex>
|
|
<div style={{ overflow: "auto", margin: "16px", height: "100%" }}>
|
|
{renderCurrentPage()}
|
|
</div>
|
|
</Flex>
|
|
</Layout>
|
|
</ConfigProvider>
|
|
);
|
|
};
|
|
|
|
export default App;
|