Add terminal in dev mode
This commit is contained in:
@@ -1,12 +1,15 @@
|
||||
import React, { useContext } from 'react';
|
||||
import { AppBar as MuiAppBar, Grid, IconButton, Toolbar } from '@mui/material';
|
||||
import { Logout } from '@mui/icons-material';
|
||||
import TerminalIcon from '@mui/icons-material/Terminal';
|
||||
import { ClientContext } from '../context/main';
|
||||
import { NetworkSelector } from './NetworkSelector';
|
||||
import { Node as NodeIcon } from '../svg-icons/node';
|
||||
import { config } from '../../config';
|
||||
|
||||
export const AppBar = () => {
|
||||
const { showSettings, logOut, handleShowSettings } = useContext(ClientContext);
|
||||
const { showSettings, logOut, handleShowSettings, handleShowTerminal } = useContext(ClientContext);
|
||||
const { IS_DEV_MODE } = config;
|
||||
|
||||
return (
|
||||
<MuiAppBar position="sticky" sx={{ boxShadow: 'none', bgcolor: 'transparent' }}>
|
||||
@@ -16,6 +19,13 @@ export const AppBar = () => {
|
||||
<NetworkSelector />
|
||||
</Grid>
|
||||
<Grid item container justifyContent="flex-end" md={12} lg={5} spacing={2}>
|
||||
{IS_DEV_MODE && (
|
||||
<Grid item>
|
||||
<IconButton size="small" onClick={handleShowTerminal} sx={{ color: 'nym.background.dark' }}>
|
||||
<TerminalIcon fontSize="small" />
|
||||
</IconButton>
|
||||
</Grid>
|
||||
)}
|
||||
<Grid item>
|
||||
<IconButton
|
||||
onClick={handleShowSettings}
|
||||
|
||||
@@ -29,6 +29,7 @@ type TClientContext = {
|
||||
userBalance: TUseuserBalance;
|
||||
showAdmin: boolean;
|
||||
showSettings: boolean;
|
||||
showTerminal: boolean;
|
||||
network?: Network;
|
||||
currency?: TCurrency;
|
||||
isLoading: boolean;
|
||||
@@ -39,6 +40,7 @@ type TClientContext = {
|
||||
getBondDetails: () => Promise<void>;
|
||||
handleShowSettings: () => void;
|
||||
handleShowAdmin: () => void;
|
||||
handleShowTerminal: () => void;
|
||||
logIn: (opts: { type: 'mnemonic' | 'password'; value: string }) => void;
|
||||
signInWithPassword: (password: string) => void;
|
||||
logOut: () => void;
|
||||
@@ -53,6 +55,7 @@ export const ClientContextProvider = ({ children }: { children: React.ReactNode
|
||||
const [currency, setCurrency] = useState<TCurrency>();
|
||||
const [showAdmin, setShowAdmin] = useState(false);
|
||||
const [showSettings, setShowSettings] = useState(false);
|
||||
const [showTerminal, setShowTerminal] = useState(false);
|
||||
const [mode] = useState<'light' | 'dark'>('light');
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [error, setError] = useState<string>();
|
||||
@@ -128,6 +131,7 @@ export const ClientContextProvider = ({ children }: { children: React.ReactNode
|
||||
|
||||
const handleShowAdmin = () => setShowAdmin((show) => !show);
|
||||
const handleShowSettings = () => setShowSettings((show) => !show);
|
||||
const handleShowTerminal = () => setShowTerminal((show) => !show);
|
||||
const switchNetwork = (_network: Network) => setNetwork(_network);
|
||||
|
||||
const memoizedValue = useMemo(
|
||||
@@ -140,6 +144,7 @@ export const ClientContextProvider = ({ children }: { children: React.ReactNode
|
||||
userBalance,
|
||||
showAdmin,
|
||||
showSettings,
|
||||
showTerminal,
|
||||
network,
|
||||
currency,
|
||||
setIsLoading,
|
||||
@@ -149,10 +154,23 @@ export const ClientContextProvider = ({ children }: { children: React.ReactNode
|
||||
getBondDetails,
|
||||
handleShowSettings,
|
||||
handleShowAdmin,
|
||||
handleShowTerminal,
|
||||
logIn,
|
||||
logOut,
|
||||
}),
|
||||
[mode, isLoading, error, clientDetails, mixnodeDetails, userBalance, showAdmin, showSettings, network, currency],
|
||||
[
|
||||
mode,
|
||||
isLoading,
|
||||
error,
|
||||
clientDetails,
|
||||
mixnodeDetails,
|
||||
userBalance,
|
||||
showAdmin,
|
||||
showSettings,
|
||||
showTerminal,
|
||||
network,
|
||||
currency,
|
||||
],
|
||||
);
|
||||
|
||||
return <ClientContext.Provider value={memoizedValue}>{children}</ClientContext.Provider>;
|
||||
|
||||
@@ -11,6 +11,7 @@ import { ErrorFallback } from './components';
|
||||
import { NymWalletTheme, WelcomeTheme } from './theme';
|
||||
import { maximizeWindow } from './utils';
|
||||
import { SignInProvider } from './pages/sign-in/context';
|
||||
import { Terminal } from './pages/terminal';
|
||||
|
||||
const App = () => {
|
||||
const { clientDetails } = useContext(ClientContext);
|
||||
@@ -30,6 +31,7 @@ const App = () => {
|
||||
<ApplicationLayout>
|
||||
<Settings />
|
||||
<Admin />
|
||||
<Terminal />
|
||||
<AppRoutes />
|
||||
</ApplicationLayout>
|
||||
</NymWalletTheme>
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
import React, { useContext, useState } from 'react';
|
||||
import { Alert, Box, Dialog, Paper, Typography } from '@mui/material';
|
||||
import TerminalIcon from '@mui/icons-material/Terminal';
|
||||
import RefreshIcon from '@mui/icons-material/Refresh';
|
||||
import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown';
|
||||
import ArrowDropUpIcon from '@mui/icons-material/ArrowDropUp';
|
||||
import { ClientContext } from '../../context/main';
|
||||
import { NymCard } from '../../components';
|
||||
import { getCurrentEpoch, getPendingDelegations, getReverseMixDelegations } from '../../requests';
|
||||
import { useGetBalance } from '../../hooks/useGetBalance';
|
||||
|
||||
const TerminalSection: React.FC<{
|
||||
heading: React.ReactNode;
|
||||
}> = ({ heading, children }) => {
|
||||
const [isCollapsed, setIsCollapsed] = useState<boolean>(true);
|
||||
|
||||
const toggleCollapse = () => {
|
||||
setIsCollapsed((prev) => !prev);
|
||||
};
|
||||
|
||||
return (
|
||||
<Box mb={2}>
|
||||
<Typography display="flex">
|
||||
{isCollapsed ? <ArrowDropDownIcon onClick={toggleCollapse} /> : <ArrowDropUpIcon onClick={toggleCollapse} />}
|
||||
<Typography ml={2} fontWeight={600}>
|
||||
{heading}
|
||||
</Typography>
|
||||
</Typography>
|
||||
{!isCollapsed && <Paper sx={{ px: 3, py: 0.5 }}>{children}</Paper>}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export const Terminal: React.FC = () => {
|
||||
const { userBalance, clientDetails, showTerminal, handleShowTerminal } = useContext(ClientContext);
|
||||
const { balance, vestingAccountInfo, currentVestingPeriod, originalVesting, fetchBalance, fetchTokenAllocation } =
|
||||
useGetBalance(clientDetails?.client_address);
|
||||
const [mixnodeDelegations, setMixnodeDelegations] = useState<any>();
|
||||
const [pendingEvents, setPendingEvents] = useState<any>();
|
||||
const [epoch, setEpoch] = useState<any>();
|
||||
const [isBusy, setIsBusy] = useState<boolean>();
|
||||
const [error, setError] = useState<any>();
|
||||
const [status, setStatus] = useState<string | undefined>();
|
||||
|
||||
const withErrorCatch = async (fn: () => Promise<void>) => {
|
||||
try {
|
||||
await fn();
|
||||
} catch (e) {
|
||||
setError(e);
|
||||
}
|
||||
};
|
||||
|
||||
const refresh = async () => {
|
||||
setError(undefined);
|
||||
setIsBusy(true);
|
||||
setStatus('Getting reverse mix delegations...');
|
||||
await withErrorCatch(async () => {
|
||||
setMixnodeDelegations(await getReverseMixDelegations());
|
||||
});
|
||||
setStatus('Getting pending delegations...');
|
||||
await withErrorCatch(async () => {
|
||||
setPendingEvents(await getPendingDelegations());
|
||||
});
|
||||
setStatus('Getting current epoch...');
|
||||
await withErrorCatch(async () => {
|
||||
setEpoch(await getCurrentEpoch());
|
||||
});
|
||||
setStatus('Fetching balance...');
|
||||
await withErrorCatch(async () => {
|
||||
await fetchBalance();
|
||||
});
|
||||
setStatus('Fetching token allocation...');
|
||||
await withErrorCatch(async () => {
|
||||
await fetchTokenAllocation();
|
||||
});
|
||||
setStatus(undefined);
|
||||
setIsBusy(false);
|
||||
};
|
||||
|
||||
React.useEffect(() => {
|
||||
refresh();
|
||||
}, []);
|
||||
|
||||
if (!showTerminal) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Dialog open onClose={handleShowTerminal} maxWidth="md" fullWidth>
|
||||
<NymCard
|
||||
title={
|
||||
<Box display="flex" alignItems="center">
|
||||
<TerminalIcon sx={{ mr: 1 }} />
|
||||
<Typography mr={4}>Terminal</Typography>
|
||||
{!isBusy && <RefreshIcon onClick={refresh} />}
|
||||
</Box>
|
||||
}
|
||||
>
|
||||
{error && <Alert color="error">{error}</Alert>}
|
||||
|
||||
{status ? (
|
||||
<Alert color="info" sx={{ mb: 2 }}>
|
||||
<strong>{status}</strong>
|
||||
</Alert>
|
||||
) : (
|
||||
<Alert color="success" sx={{ mb: 2 }}>
|
||||
<strong>Data loading complete</strong>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
<TerminalSection heading="Client Details">
|
||||
<pre>{JSON.stringify(clientDetails, null, 2)}</pre>
|
||||
</TerminalSection>
|
||||
|
||||
<TerminalSection heading="User Balance">
|
||||
<pre>{JSON.stringify(userBalance, null, 2)}</pre>
|
||||
</TerminalSection>
|
||||
|
||||
<TerminalSection
|
||||
heading={
|
||||
<>
|
||||
<code>useGetBalance</code> Balance
|
||||
</>
|
||||
}
|
||||
>
|
||||
<pre>{JSON.stringify(balance, null, 2)}</pre>
|
||||
</TerminalSection>
|
||||
|
||||
<TerminalSection
|
||||
heading={
|
||||
<>
|
||||
<code>useGetBalance</code> Vesting Account Info
|
||||
</>
|
||||
}
|
||||
>
|
||||
<pre>{JSON.stringify(vestingAccountInfo, null, 2)}</pre>
|
||||
</TerminalSection>
|
||||
|
||||
<TerminalSection
|
||||
heading={
|
||||
<>
|
||||
<code>useGetBalance</code> Current Vest Period
|
||||
</>
|
||||
}
|
||||
>
|
||||
<pre>{JSON.stringify(currentVestingPeriod, null, 2)}</pre>
|
||||
</TerminalSection>
|
||||
|
||||
<TerminalSection heading="Original Vesting">
|
||||
<pre>{JSON.stringify(originalVesting, null, 2)}</pre>
|
||||
</TerminalSection>
|
||||
|
||||
<TerminalSection heading="Mixnode Delegations">
|
||||
<pre>{JSON.stringify(mixnodeDelegations, null, 2)}</pre>
|
||||
</TerminalSection>
|
||||
|
||||
<TerminalSection heading="Pending Delegation Events">
|
||||
<pre>{JSON.stringify(pendingEvents, null, 2)}</pre>
|
||||
</TerminalSection>
|
||||
|
||||
<TerminalSection heading="Epoch">
|
||||
<pre>{JSON.stringify(epoch, null, 2)}</pre>
|
||||
</TerminalSection>
|
||||
</NymCard>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user