217 lines
9.2 KiB
JavaScript
217 lines
9.2 KiB
JavaScript
import "./style.scss";
|
|
|
|
import { useMediaQuery } from "@mui/material";
|
|
import CssBaseline from "@mui/material/CssBaseline";
|
|
import { styled, ThemeProvider } from "@mui/material/styles";
|
|
import { lazy, Suspense, useCallback, useEffect, useState } from "react";
|
|
import toast, { Toaster } from "react-hot-toast";
|
|
import { Navigate, Route, Routes, useLocation } from "react-router-dom";
|
|
import { useAccount, useConnect, useChainId, useConfig, usePublicClient, injected } from "wagmi";
|
|
|
|
import Messages from "./components/Messages/Messages";
|
|
import NavDrawer from "./components/Sidebar/NavDrawer";
|
|
import Sidebar from "./components/Sidebar/Sidebar";
|
|
import TopBar from "./components/TopBar/TopBar";
|
|
|
|
import { shouldTriggerSafetyCheck } from "./helpers";
|
|
import { isNetworkAvailable } from "./constants";
|
|
import useTheme from "./hooks/useTheme";
|
|
import { dark as darkTheme } from "./themes/dark.js";
|
|
import { girth as gTheme } from "./themes/girth.js";
|
|
import { light as lightTheme } from "./themes/light.js";
|
|
|
|
// Dynamic Imports for code splitting
|
|
const Bonds = lazy(() => import("./containers/Bond/Bonds"));
|
|
const BondModalContainer = lazy(() => import("./containers/Bond/BondModal"));
|
|
const StakeContainer = lazy(() => import("./containers/Stake/StakeContainer"));
|
|
const TreasuryDashboard = lazy(() => import("./containers/TreasuryDashboard/TreasuryDashboard"));
|
|
const Faucet = lazy(() => import("./containers/Faucet/Faucet"));
|
|
const Dex = lazy(() => import("./containers/Dex/Dex"));
|
|
const Bridge = lazy(() => import("./containers/Bridge/Bridge"));
|
|
const NotFound = lazy(() => import("./containers/NotFound/NotFound"));
|
|
|
|
const PREFIX = "App";
|
|
|
|
const classes = {
|
|
drawer: `${PREFIX}-drawer`,
|
|
content: `${PREFIX}-content`,
|
|
contentShift: `${PREFIX}-contentShift`,
|
|
toolbar: `${PREFIX}-toolbar`,
|
|
drawerPaper: `${PREFIX}-drawerPaper`,
|
|
notification: `${PREFIX}-notification`,
|
|
};
|
|
|
|
const StyledDiv = styled("div")(({ theme }) => ({
|
|
[`& .${classes.drawer}`]: {
|
|
[theme.breakpoints.up("md")]: {
|
|
width: drawerWidth,
|
|
flexShrink: 0,
|
|
},
|
|
},
|
|
|
|
[`& .${classes.content}`]: {
|
|
flexGrow: 1,
|
|
padding: "15px",
|
|
transition: theme.transitions.create("margin", {
|
|
easing: theme.transitions.easing.sharp,
|
|
duration: transitionDuration,
|
|
}),
|
|
marginLeft: drawerWidth,
|
|
marginTop: "-48.5px",
|
|
},
|
|
|
|
[`& .${classes.contentShift}`]: {
|
|
transition: theme.transitions.create("margin", {
|
|
easing: theme.transitions.easing.easeOut,
|
|
duration: transitionDuration,
|
|
}),
|
|
marginLeft: 0,
|
|
},
|
|
|
|
// necessary for content to be below app bar
|
|
[`& .${classes.toolbar}`]: theme.mixins.toolbar,
|
|
|
|
[`& .${classes.drawerPaper}`]: {
|
|
width: drawerWidth,
|
|
},
|
|
|
|
[`& .${classes.notification}`]: {
|
|
marginLeft: "264px",
|
|
},
|
|
}));
|
|
|
|
// 😬 Sorry for all the console logging
|
|
const DEBUG = false;
|
|
|
|
// 🛰 providers
|
|
if (DEBUG) console.log("📡 Connecting to Mainnet Ethereum");
|
|
// 🔭 block explorer URL
|
|
// const blockExplorer = targetNetwork.blockExplorer;
|
|
|
|
const drawerWidth = 264;
|
|
const transitionDuration = 969;
|
|
function App() {
|
|
const location = useLocation();
|
|
const [theme, toggleTheme] = useTheme();
|
|
|
|
const config = useConfig();
|
|
const { connect, error: errorMessage } = useConnect();
|
|
const tryConnectInjected = () => connect({ connector: injected() });
|
|
|
|
const bondIndexes = [];
|
|
|
|
const [wrongNetworkToastId, setWrongNetworkToastId] = useState(null);
|
|
const [isSidebarExpanded, setIsSidebarExpanded] = useState(false);
|
|
const [mobileOpen, setMobileOpen] = useState(false);
|
|
|
|
const { address = "", chainId: addressChainId, isConnected, isReconnecting } = useAccount();
|
|
|
|
const provider = usePublicClient();
|
|
const chainId = useChainId();
|
|
|
|
const isSmallerScreen = useMediaQuery("(max-width: 1047px)");
|
|
const isSmallScreen = useMediaQuery("(max-width: 600px)");
|
|
|
|
useEffect(() => {
|
|
if (shouldTriggerSafetyCheck()) {
|
|
toast.success("Safety Check: Always verify you're on app.dao.ghostchain.io!", { duration: 5000 });
|
|
}
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
if (isConnected && chainId !== addressChainId) {
|
|
const toastId = toast.loading("You are connected to wrong network. Use one of the deployed networks please.", {
|
|
position: 'bottom-right'
|
|
});
|
|
setWrongNetworkToastId(toastId);
|
|
} else {
|
|
if (wrongNetworkToastId) {
|
|
toast.dismiss(wrongNetworkToastId);
|
|
setWrongNetworkToastId(null);
|
|
}
|
|
}
|
|
}, [chainId, addressChainId, isConnected])
|
|
|
|
useEffect(() => {
|
|
if (errorMessage) {
|
|
toast.error("No injected connectors found in your browser. Download Metamask extension or visit EIP-1193 for more details.", { duration: 5000 });
|
|
}
|
|
}, [errorMessage]);
|
|
|
|
const handleDrawerToggle = () => {
|
|
setMobileOpen(!mobileOpen);
|
|
};
|
|
|
|
const handleSidebarClose = () => {
|
|
setIsSidebarExpanded(false);
|
|
};
|
|
|
|
const themeMode = theme === "light" ? lightTheme : theme === "dark" ? darkTheme : gTheme;
|
|
|
|
const chainExists = isNetworkAvailable(chainId, addressChainId);
|
|
|
|
useEffect(() => {
|
|
if (isSidebarExpanded) handleSidebarClose();
|
|
}, [location]);
|
|
|
|
return (
|
|
<StyledDiv>
|
|
<ThemeProvider theme={themeMode}>
|
|
<CssBaseline />
|
|
<div className={`app ${isSmallerScreen && "tablet"} ${isSmallScreen && "mobile"} ${theme}`}>
|
|
<Toaster>{t => <Messages toast={t} />}</Toaster>
|
|
<TopBar
|
|
wrongNetworkToastId={wrongNetworkToastId}
|
|
setWrongNetworkToastId={setWrongNetworkToastId}
|
|
address={address}
|
|
chainId={addressChainId ? addressChainId : chainId}
|
|
chainExists={chainExists}
|
|
handleDrawerToggle={handleDrawerToggle}
|
|
connect={tryConnectInjected}
|
|
/>
|
|
<nav className={classes.drawer}>
|
|
{isSmallerScreen ? (
|
|
<NavDrawer chainId={chainId} addressChainId={addressChainId} mobileOpen={mobileOpen} handleDrawerToggle={handleDrawerToggle} />
|
|
) : (
|
|
<Sidebar chainId={chainId} addressChainId={addressChainId} />
|
|
)}
|
|
</nav>
|
|
|
|
<div className={`${classes.content} ${isSmallerScreen && classes.contentShift}`}>
|
|
<Suspense fallback={<div></div>}>
|
|
<Routes>
|
|
<Route path="/" element={<Navigate to={chainExists ? "/dashboard" : "/empty"} />} />
|
|
{chainExists &&
|
|
<>
|
|
<Route path="/dashboard" element={<TreasuryDashboard chainId={addressChainId ? addressChainId : chainId} />} />
|
|
<Route path="/bonds" element={<Bonds connect={tryConnectInjected} address={address} chainId={addressChainId ? addressChainId : chainId} />} />
|
|
<Route path="/bonds/:id" element={<BondModalContainer connect={tryConnectInjected} address={address} chainId={addressChainId ? addressChainId : chainId} />} />
|
|
<Route path="/stake" element={<StakeContainer connect={tryConnectInjected} address={address} chainId={addressChainId ? addressChainId : chainId}/>} />
|
|
<Route path="/faucet" element={<Faucet config={config} connect={tryConnectInjected} address={address} chainId={addressChainId ? addressChainId : chainId} />} />
|
|
<Route path="/bridge" element={<Bridge config={config} connect={tryConnectInjected} address={address} chainId={addressChainId ? addressChainId : chainId} />} />
|
|
<Route path="/dex/:name" element={<Dex connect={tryConnectInjected} address={address} chainId={addressChainId ? addressChainId : chainId} />} />
|
|
</>
|
|
}
|
|
<Route path="/empty" element={<NotFound
|
|
wrongNetworkToastId={wrongNetworkToastId}
|
|
setWrongNetworkToastId={setWrongNetworkToastId}
|
|
chainId={addressChainId ? addressChainId : chainId}
|
|
chainExists={chainExists}
|
|
/>} />
|
|
<Route path="*" element={<NotFound
|
|
wrongNetworkToastId={wrongNetworkToastId}
|
|
setWrongNetworkToastId={setWrongNetworkToastId}
|
|
chainId={addressChainId ? addressChainId : chainId}
|
|
chainExists={chainExists}
|
|
/>} />
|
|
</Routes>
|
|
</Suspense>
|
|
</div>
|
|
</div>
|
|
</ThemeProvider>
|
|
</StyledDiv>
|
|
);
|
|
}
|
|
|
|
export default App;
|