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;