React / React DOM / Types upgrade to version 18 (#2830)
* new react and reactdom packages in wallet * new react and reactdom packages in root * new react and reactdom packages in nym connect * new react and reactdom packages in root * update react and reactdom for explorer * react and react-dom upgrade for ts-packages remove unused import fix linting error * use custom FC typing move typings folder * fix type error
This commit is contained in:
@@ -18,8 +18,8 @@
|
||||
"d3-scale": "^4.0.0",
|
||||
"date-fns": "^2.24.0",
|
||||
"i18n-iso-countries": "^6.8.0",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-error-boundary": "^3.1.4",
|
||||
"react-google-charts": "^3.0.15",
|
||||
"react-identicons": "^1.2.5",
|
||||
@@ -48,8 +48,8 @@
|
||||
"@types/geojson": "^7946.0.8",
|
||||
"@types/jest": "^27.0.1",
|
||||
"@types/node": "^16.7.13",
|
||||
"@types/react": "^17.0.34",
|
||||
"@types/react-dom": "^17.0.9",
|
||||
"@types/react": "^18.0.26",
|
||||
"@types/react-dom": "^18.0.10",
|
||||
"@types/react-simple-maps": "^1.0.6",
|
||||
"@types/react-tooltip": "^4.2.4",
|
||||
"@types/topojson-client": "^3.1.0",
|
||||
|
||||
@@ -4,7 +4,7 @@ import { MobileNav } from './components/MobileNav';
|
||||
import { Routes } from './routes/index';
|
||||
import { useIsMobile } from './hooks/useIsMobile';
|
||||
|
||||
export const App: React.FC = () => {
|
||||
export const App: FCWithChildren = () => {
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
if (isMobile) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Typography } from '@mui/material';
|
||||
import * as React from 'react';
|
||||
|
||||
export const ComponentError: React.FC<{ text: string }> = ({ text }) => (
|
||||
export const ComponentError: FCWithChildren<{ text: string }> = ({ text }) => (
|
||||
<Typography
|
||||
sx={{ marginTop: 2, color: 'primary.main', fontSize: 10 }}
|
||||
variant="body1"
|
||||
|
||||
@@ -10,7 +10,7 @@ type ContentCardProps = {
|
||||
onClick?: ReactEventHandler;
|
||||
};
|
||||
|
||||
export const ContentCard: React.FC<ContentCardProps> = ({
|
||||
export const ContentCard: FCWithChildren<ContentCardProps> = ({
|
||||
title,
|
||||
Icon,
|
||||
Action,
|
||||
|
||||
@@ -4,7 +4,7 @@ import { ExpandLess, ExpandMore } from '@mui/icons-material';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
import { Tooltip } from '@nymproject/react/tooltip/Tooltip';
|
||||
|
||||
export const CustomColumnHeading: React.FC<{ headingTitle: string; tooltipInfo?: string }> = ({
|
||||
export const CustomColumnHeading: FCWithChildren<{ headingTitle: string; tooltipInfo?: string }> = ({
|
||||
headingTitle,
|
||||
tooltipInfo,
|
||||
}) => {
|
||||
|
||||
@@ -43,7 +43,7 @@ function formatCellValues(val: string | number, field: string) {
|
||||
return val;
|
||||
}
|
||||
|
||||
export const DetailTable: React.FC<{
|
||||
export const DetailTable: FCWithChildren<{
|
||||
tableName: string;
|
||||
columnsData: ColumnsType[];
|
||||
rows: MixnodeRowType[] | GatewayEnrichedRowType[];
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Typography } from '@mui/material';
|
||||
import { Socials } from './Socials';
|
||||
import { useIsMobile } from '../hooks/useIsMobile';
|
||||
|
||||
export const Footer: React.FC = () => {
|
||||
export const Footer: FCWithChildren = () => {
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
return (
|
||||
|
||||
@@ -13,7 +13,7 @@ import { currencyToString } from '../../utils/currency';
|
||||
import { useMixnodeContext } from '../../context/mixnode';
|
||||
import { useIsMobile } from '../../hooks/useIsMobile';
|
||||
|
||||
export const BondBreakdownTable: React.FC = () => {
|
||||
export const BondBreakdownTable: FCWithChildren = () => {
|
||||
const { mixNode, delegations, uniqDelegations } = useMixnodeContext();
|
||||
const [showDelegations, toggleShowDelegations] = React.useState<boolean>(false);
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ interface MixNodeDetailProps {
|
||||
mixnodeDescription: MixNodeDescriptionResponse;
|
||||
}
|
||||
|
||||
export const MixNodeDetailSection: React.FC<MixNodeDetailProps> = ({ mixNodeRow, mixnodeDescription }) => {
|
||||
export const MixNodeDetailSection: FCWithChildren<MixNodeDetailProps> = ({ mixNodeRow, mixnodeDescription }) => {
|
||||
const theme = useTheme();
|
||||
const palette = [theme.palette.text.primary];
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
@@ -6,7 +6,7 @@ import { Box } from '@mui/system';
|
||||
const parseToNumber = (value: number | undefined | string) =>
|
||||
typeof value === 'string' ? parseInt(value || '', 10) : value || 0;
|
||||
|
||||
export const EconomicsProgress: React.FC<
|
||||
export const EconomicsProgress: FCWithChildren<
|
||||
LinearProgressProps & {
|
||||
threshold?: number;
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ const formatCellValues = (value: EconomicsRowsType, field: string) => {
|
||||
);
|
||||
};
|
||||
|
||||
export const DelegatorsInfoTable: React.FC<UniversalTableProps<EconomicsInfoRowWithIndex>> = ({
|
||||
export const DelegatorsInfoTable: FCWithChildren<UniversalTableProps<EconomicsInfoRowWithIndex>> = ({
|
||||
tableName,
|
||||
columnsData,
|
||||
rows,
|
||||
|
||||
@@ -36,7 +36,7 @@ export const getMixNodeStatusText = (status: MixnodeStatus) => {
|
||||
}
|
||||
};
|
||||
|
||||
export const MixNodeStatus: React.FC<MixNodeStatusProps> = ({ status }) => {
|
||||
export const MixNodeStatus: FCWithChildren<MixNodeStatusProps> = ({ status }) => {
|
||||
const theme = useTheme();
|
||||
const Icon = React.useMemo(() => getMixNodeIcon(status), [status]);
|
||||
const color = React.useMemo(() => getMixNodeStatusColor(theme, status), [status, theme]);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import { MenuItem } from '@mui/material';
|
||||
import Select from '@mui/material/Select';
|
||||
import { SelectInputProps } from '@mui/material/Select/SelectInput';
|
||||
import { SelectChangeEvent } from '@mui/material/Select/SelectInput';
|
||||
import { SxProps } from '@mui/system';
|
||||
import { MixNodeStatus } from './Status';
|
||||
import { MixnodeStatus, MixnodeStatusWithAll } from '../../typeDefs/explorer-api';
|
||||
@@ -16,14 +16,18 @@ interface MixNodeStatusDropdownProps {
|
||||
onSelectionChanged?: (status?: MixnodeStatusWithAll) => void;
|
||||
}
|
||||
|
||||
export const MixNodeStatusDropdown: React.FC<MixNodeStatusDropdownProps> = ({ status, onSelectionChanged, sx }) => {
|
||||
export const MixNodeStatusDropdown: FCWithChildren<MixNodeStatusDropdownProps> = ({
|
||||
status,
|
||||
onSelectionChanged,
|
||||
sx,
|
||||
}) => {
|
||||
const isMobile = useIsMobile();
|
||||
const [statusValue, setStatusValue] = React.useState<MixnodeStatusWithAll>(status || MixnodeStatusWithAll.all);
|
||||
const onChange: SelectInputProps<MixnodeStatusWithAll>['onChange'] = React.useCallback(
|
||||
({ target: { value } }) => {
|
||||
setStatusValue(value);
|
||||
const onChange = React.useCallback(
|
||||
(event: SelectChangeEvent) => {
|
||||
setStatusValue(event.target.value as MixnodeStatusWithAll);
|
||||
if (onSelectionChanged) {
|
||||
onSelectionChanged(value);
|
||||
onSelectionChanged(event.target.value as MixnodeStatusWithAll);
|
||||
}
|
||||
},
|
||||
[onSelectionChanged],
|
||||
|
||||
@@ -25,11 +25,7 @@ import { NYM_WEBSITE } from '../api/constants';
|
||||
import { ExpandableButton } from './Nav';
|
||||
import { DarkLightSwitchMobile } from './Switch';
|
||||
|
||||
type MobileNavProps = {
|
||||
children: React.ReactNode;
|
||||
};
|
||||
|
||||
export const MobileNav: React.FC<{ children: React.ReactNode }> = ({ children }: MobileNavProps) => {
|
||||
export const MobileNav: FCWithChildren = ({ children }) => {
|
||||
const theme = useTheme();
|
||||
const { navState, updateNavState } = useMainContext();
|
||||
const [drawerOpen, setDrawerOpen] = React.useState(false);
|
||||
|
||||
@@ -87,7 +87,7 @@ type ExpandableButtonType = {
|
||||
setToActive: (num: number) => void;
|
||||
};
|
||||
|
||||
export const ExpandableButton: React.FC<ExpandableButtonType> = ({
|
||||
export const ExpandableButton: FCWithChildren<ExpandableButtonType> = ({
|
||||
id,
|
||||
url,
|
||||
setToActive,
|
||||
@@ -230,7 +230,7 @@ ExpandableButton.defaultProps = {
|
||||
closeDrawer: undefined,
|
||||
};
|
||||
|
||||
export const Nav: React.FC = ({ children }) => {
|
||||
export const Nav: FCWithChildren = ({ children }) => {
|
||||
const { updateNavState, navState } = useMainContext();
|
||||
const [drawerIsOpen, setDrawerToOpen] = React.useState(false);
|
||||
const [fixedOpen, setFixedOpen] = React.useState(false);
|
||||
|
||||
@@ -12,7 +12,7 @@ export const TWITTER_LINK = 'https://twitter.com/nymproject';
|
||||
export const GITHUB_LINK = 'https://github.com/nymtech';
|
||||
export const DISCORD_LINK = 'https://discord.gg/nym';
|
||||
|
||||
export const Socials: React.FC<{ isFooter?: boolean }> = ({ isFooter }) => {
|
||||
export const Socials: FCWithChildren<{ isFooter?: boolean }> = ({ isFooter }) => {
|
||||
const theme = useTheme();
|
||||
const color = isFooter
|
||||
? theme.palette.nym.networkExplorer.footer.socialIcons
|
||||
|
||||
@@ -11,7 +11,14 @@ interface StatsCardProps {
|
||||
onClick?: () => void;
|
||||
color?: string;
|
||||
}
|
||||
export const StatsCard: React.FC<StatsCardProps> = ({ icon, title, count, onClick, errorMsg, color: colorProp }) => {
|
||||
export const StatsCard: FCWithChildren<StatsCardProps> = ({
|
||||
icon,
|
||||
title,
|
||||
count,
|
||||
onClick,
|
||||
errorMsg,
|
||||
color: colorProp,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
const color = colorProp || theme.palette.text.primary;
|
||||
return (
|
||||
|
||||
@@ -51,7 +51,7 @@ export const DarkLightSwitch = styled(Switch)(({ theme }) => ({
|
||||
},
|
||||
}));
|
||||
|
||||
export const DarkLightSwitchMobile: React.FC = () => {
|
||||
export const DarkLightSwitchMobile: FCWithChildren = () => {
|
||||
const { toggleMode } = useMainContext();
|
||||
return (
|
||||
<Button onClick={() => toggleMode()} data-testid="switch-button">
|
||||
@@ -60,7 +60,7 @@ export const DarkLightSwitchMobile: React.FC = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export const DarkLightSwitchDesktop: React.FC<{ defaultChecked: boolean }> = ({ defaultChecked }) => {
|
||||
export const DarkLightSwitchDesktop: FCWithChildren<{ defaultChecked: boolean }> = ({ defaultChecked }) => {
|
||||
const { toggleMode } = useMainContext();
|
||||
return (
|
||||
<Button sx={{ paddingLeft: 0 }} onClick={() => toggleMode()} data-testid="switch-button">
|
||||
|
||||
@@ -16,7 +16,7 @@ type TableToolBarProps = {
|
||||
childrenAfter?: React.ReactNode;
|
||||
};
|
||||
|
||||
export const TableToolbar: React.FC<TableToolBarProps> = ({
|
||||
export const TableToolbar: FCWithChildren<TableToolBarProps> = ({
|
||||
searchTerm,
|
||||
onChangeSearch,
|
||||
onChangePageSize,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import { Typography } from '@mui/material';
|
||||
|
||||
export const Title: React.FC<{ text: string }> = ({ text }) => (
|
||||
export const Title: FCWithChildren<{ text: string }> = ({ text }) => (
|
||||
<Typography
|
||||
variant="h5"
|
||||
sx={{
|
||||
|
||||
@@ -19,7 +19,7 @@ interface TableProps {
|
||||
loading: boolean;
|
||||
}
|
||||
|
||||
export const TwoColSmallTable: React.FC<TableProps> = ({
|
||||
export const TwoColSmallTable: FCWithChildren<TableProps> = ({
|
||||
loading,
|
||||
title,
|
||||
icons,
|
||||
|
||||
@@ -50,7 +50,7 @@ type DataGridProps = {
|
||||
rows: any;
|
||||
loading?: boolean;
|
||||
};
|
||||
export const UniversalDataGrid: React.FC<DataGridProps> = ({ rows, columns, loading, pagination, pageSize }) => {
|
||||
export const UniversalDataGrid: FCWithChildren<DataGridProps> = ({ rows, columns, loading, pagination, pageSize }) => {
|
||||
if (loading) return <LinearProgress />;
|
||||
if (!loading)
|
||||
return (
|
||||
|
||||
@@ -17,7 +17,7 @@ type FormattedDateRecord = [string, number];
|
||||
type FormattedChartHeadings = string[];
|
||||
type FormattedChartData = [FormattedChartHeadings | FormattedDateRecord];
|
||||
|
||||
export const UptimeChart: React.FC<ChartProps> = ({ title, xLabel, yLabel, uptimeStory, loading }) => {
|
||||
export const UptimeChart: FCWithChildren<ChartProps> = ({ title, xLabel, yLabel, uptimeStory, loading }) => {
|
||||
const [formattedChartData, setFormattedChartData] = React.useState<FormattedChartData>();
|
||||
const theme = useTheme();
|
||||
const color = theme.palette.text.primary;
|
||||
|
||||
@@ -14,7 +14,7 @@ type MapProps = {
|
||||
loading: boolean;
|
||||
};
|
||||
|
||||
export const WorldMap: React.FC<MapProps> = ({ countryData, userLocation, loading }) => {
|
||||
export const WorldMap: FCWithChildren<MapProps> = ({ countryData, userLocation, loading }) => {
|
||||
const { palette } = useTheme();
|
||||
|
||||
const colorScale = React.useMemo(() => {
|
||||
|
||||
@@ -46,7 +46,7 @@ export const MainContext = React.createContext<State>({
|
||||
|
||||
export const useMainContext = (): React.ContextType<typeof MainContext> => React.useContext<State>(MainContext);
|
||||
|
||||
export const MainContextProvider: React.FC = ({ children }) => {
|
||||
export const MainContextProvider: FCWithChildren = ({ children }) => {
|
||||
// light/dark mode
|
||||
const [mode, setMode] = React.useState<PaletteMode>('dark');
|
||||
|
||||
|
||||
@@ -37,13 +37,14 @@ export const useMixnodeContext = (): React.ContextType<typeof MixnodeContext> =>
|
||||
|
||||
interface MixnodeContextProviderProps {
|
||||
mixId: string;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a state context for a mixnode by identity
|
||||
* @param mixId The mixID of the mixnode
|
||||
*/
|
||||
export const MixnodeContextProvider: React.FC<MixnodeContextProviderProps> = ({ mixId, children }) => {
|
||||
export const MixnodeContextProvider: FCWithChildren<MixnodeContextProviderProps> = ({ mixId, children }) => {
|
||||
const [mixNode, fetchMixnodeById, clearMixnodeById] = useApiState<MixNodeResponseItem | undefined>(
|
||||
mixId,
|
||||
Api.fetchMixnodeByID,
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Alert, AlertTitle, Container } from '@mui/material';
|
||||
import { NymThemeProvider } from '@nymproject/mui-theme';
|
||||
import { NymLogo } from '@nymproject/react/logo/NymLogo';
|
||||
|
||||
export const ErrorBoundaryContent: React.FC<FallbackProps> = ({ error }) => (
|
||||
export const ErrorBoundaryContent: FCWithChildren<FallbackProps> = ({ error }) => (
|
||||
<NymThemeProvider mode="dark">
|
||||
<Container sx={{ py: 4 }}>
|
||||
<NymLogo height="75px" width="75px" />
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
|
||||
export const GatewaysSVG: React.FC = () => {
|
||||
export const GatewaysSVG: FCWithChildren = () => {
|
||||
const theme = useTheme();
|
||||
const color = theme.palette.text.primary;
|
||||
return (
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
|
||||
export const LightSwitchSVG: React.FC = () => {
|
||||
export const LightSwitchSVG: FCWithChildren = () => {
|
||||
const { palette } = useTheme();
|
||||
return (
|
||||
<svg width="26" height="26" viewBox="0 0 26 26" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
|
||||
export const MixnodesSVG: React.FC = () => {
|
||||
export const MixnodesSVG: FCWithChildren = () => {
|
||||
const theme = useTheme();
|
||||
const color = theme.palette.text.primary;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as React from 'react';
|
||||
|
||||
export const MobileDrawerClose: React.FC = (props) => (
|
||||
export const MobileDrawerClose: FCWithChildren = (props) => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-3 -5 24 24" width="25" height="25" {...props}>
|
||||
<path
|
||||
d="M0 12H13V10H0V12ZM0 7H10V5H0V7ZM0 0V2H13V0H0ZM18 9.59L14.42 6L18 2.41L16.59 1L11.59 6L16.59 11L18 9.59Z"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
|
||||
export const NetworkComponentsSVG: React.FC = () => {
|
||||
export const NetworkComponentsSVG: FCWithChildren = () => {
|
||||
const theme = useTheme();
|
||||
const color = theme.palette.nym.networkExplorer.nav.text;
|
||||
return (
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
|
||||
export const NodemapSVG: React.FC = () => {
|
||||
export const NodemapSVG: FCWithChildren = () => {
|
||||
const theme = useTheme();
|
||||
const color = theme.palette.nym.networkExplorer.nav.text;
|
||||
return (
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
|
||||
export const OverviewSVG: React.FC = () => {
|
||||
export const OverviewSVG: FCWithChildren = () => {
|
||||
const theme = useTheme();
|
||||
const color = theme.palette.nym.networkExplorer.nav.text;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
|
||||
export const ValidatorsSVG: React.FC = () => {
|
||||
export const ValidatorsSVG: FCWithChildren = () => {
|
||||
const theme = useTheme();
|
||||
const color = theme.palette.text.primary;
|
||||
return (
|
||||
|
||||
@@ -6,7 +6,7 @@ interface DiscordIconProps {
|
||||
color?: string;
|
||||
}
|
||||
|
||||
export const DiscordIcon: React.FC<DiscordIconProps> = ({ size, color: colorProp }) => {
|
||||
export const DiscordIcon: FCWithChildren<DiscordIconProps> = ({ size, color: colorProp }) => {
|
||||
const theme = useTheme();
|
||||
const color = colorProp || theme.palette.text.primary;
|
||||
return (
|
||||
|
||||
@@ -6,7 +6,7 @@ interface GitHubIconProps {
|
||||
color?: string;
|
||||
}
|
||||
|
||||
export const GitHubIcon: React.FC<GitHubIconProps> = ({ size, color: colorProp }) => {
|
||||
export const GitHubIcon: FCWithChildren<GitHubIconProps> = ({ size, color: colorProp }) => {
|
||||
const theme = useTheme();
|
||||
const color = colorProp || theme.palette.text.primary;
|
||||
return (
|
||||
|
||||
@@ -6,7 +6,7 @@ interface TelegramIconProps {
|
||||
color?: string;
|
||||
}
|
||||
|
||||
export const TelegramIcon: React.FC<TelegramIconProps> = ({ size, color: colorProp }) => {
|
||||
export const TelegramIcon: FCWithChildren<TelegramIconProps> = ({ size, color: colorProp }) => {
|
||||
const theme = useTheme();
|
||||
const color = colorProp || theme.palette.text.primary;
|
||||
return (
|
||||
|
||||
@@ -6,7 +6,7 @@ interface TwitterIconProps {
|
||||
color?: string;
|
||||
}
|
||||
|
||||
export const TwitterIcon: React.FC<TwitterIconProps> = ({ size, color: colorProp }) => {
|
||||
export const TwitterIcon: FCWithChildren<TwitterIconProps> = ({ size, color: colorProp }) => {
|
||||
const theme = useTheme();
|
||||
const color = colorProp || theme.palette.text.primary;
|
||||
return (
|
||||
|
||||
+17
-13
@@ -1,5 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
import { BrowserRouter as Router } from 'react-router-dom';
|
||||
import { ErrorBoundary } from 'react-error-boundary';
|
||||
import { App } from './App';
|
||||
@@ -8,15 +8,19 @@ import './styles.css';
|
||||
import { NetworkExplorerThemeProvider } from './theme';
|
||||
import { ErrorBoundaryContent } from './errors/ErrorBoundaryContent';
|
||||
|
||||
ReactDOM.render(
|
||||
<ErrorBoundary FallbackComponent={ErrorBoundaryContent}>
|
||||
<MainContextProvider>
|
||||
<NetworkExplorerThemeProvider>
|
||||
<Router>
|
||||
<App />
|
||||
</Router>
|
||||
</NetworkExplorerThemeProvider>
|
||||
</MainContextProvider>
|
||||
</ErrorBoundary>,
|
||||
document.getElementById('app'),
|
||||
);
|
||||
const elem = document.getElementById('app');
|
||||
|
||||
if (elem) {
|
||||
const root = createRoot(elem);
|
||||
root.render(
|
||||
<ErrorBoundary FallbackComponent={ErrorBoundaryContent}>
|
||||
<MainContextProvider>
|
||||
<NetworkExplorerThemeProvider>
|
||||
<Router>
|
||||
<App />
|
||||
</Router>
|
||||
</NetworkExplorerThemeProvider>
|
||||
</MainContextProvider>
|
||||
</ErrorBoundary>,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import { useNavigate } from 'react-router-dom';
|
||||
import { NymLogo } from '@nymproject/react/logo/NymLogo';
|
||||
import { useMainContext } from '../../context/main';
|
||||
|
||||
export const Page404: React.FC = () => {
|
||||
export const Page404 = () => {
|
||||
const navigate = useNavigate();
|
||||
const { mode } = useMainContext();
|
||||
const theme = useTheme();
|
||||
|
||||
@@ -129,7 +129,7 @@ const PageGatewayDetailsWithState = ({ selectedGateway }: { selectedGateway: Gat
|
||||
/**
|
||||
* Guard component to handle loading and not found states
|
||||
*/
|
||||
const PageGatewayDetailGuard: React.FC = () => {
|
||||
const PageGatewayDetailGuard: FCWithChildren = () => {
|
||||
const [selectedGateway, setSelectedGateway] = React.useState<GatewayResponseItem | undefined>();
|
||||
const { gateways } = useMainContext();
|
||||
const { id } = useParams<{ id: string | undefined }>();
|
||||
@@ -170,7 +170,7 @@ const PageGatewayDetailGuard: React.FC = () => {
|
||||
/**
|
||||
* Wrapper component that adds the mixnode content based on the `id` in the address URL
|
||||
*/
|
||||
export const PageGatewayDetail: React.FC = () => {
|
||||
export const PageGatewayDetail: FCWithChildren = () => {
|
||||
const { id } = useParams<{ id: string | undefined }>();
|
||||
|
||||
if (!id) {
|
||||
|
||||
@@ -15,7 +15,7 @@ import { Tooltip } from '../../components/Tooltip';
|
||||
import { BIG_DIPPER } from '../../api/constants';
|
||||
import { splice } from '../../utils';
|
||||
|
||||
export const PageGateways: React.FC = () => {
|
||||
export const PageGateways: FCWithChildren = () => {
|
||||
const { gateways } = useMainContext();
|
||||
const [filteredGateways, setFilteredGateways] = React.useState<GatewayResponse>([]);
|
||||
const [pageSize, setPageSize] = React.useState<string>('50');
|
||||
|
||||
@@ -62,7 +62,7 @@ const columns: ColumnsType[] = [
|
||||
/**
|
||||
* Shows mix node details
|
||||
*/
|
||||
const PageMixnodeDetailWithState: React.FC = () => {
|
||||
const PageMixnodeDetailWithState: FCWithChildren = () => {
|
||||
const { mixNode, mixNodeRow, description, stats, status, uptimeStory, uniqDelegations } = useMixnodeContext();
|
||||
|
||||
return (
|
||||
@@ -181,7 +181,7 @@ const PageMixnodeDetailWithState: React.FC = () => {
|
||||
/**
|
||||
* Guard component to handle loading and not found states
|
||||
*/
|
||||
const PageMixnodeDetailGuard: React.FC = () => {
|
||||
const PageMixnodeDetailGuard: FCWithChildren = () => {
|
||||
const { mixNode } = useMixnodeContext();
|
||||
const { id } = useParams<{ id: string | undefined }>();
|
||||
|
||||
@@ -215,7 +215,7 @@ const PageMixnodeDetailGuard: React.FC = () => {
|
||||
/**
|
||||
* Wrapper component that adds the mixnode content based on the `id` in the address URL
|
||||
*/
|
||||
export const PageMixnodeDetail: React.FC = () => {
|
||||
export const PageMixnodeDetail: FCWithChildren = () => {
|
||||
const { id } = useParams<{ id: string | undefined }>();
|
||||
|
||||
if (!id) {
|
||||
|
||||
@@ -35,7 +35,7 @@ const getCellStyles = (theme: Theme, row: MixnodeRowType, textColor?: string): S
|
||||
...getCellFontStyle(theme, row, textColor),
|
||||
});
|
||||
|
||||
export const PageMixnodes: React.FC = () => {
|
||||
export const PageMixnodes: FCWithChildren = () => {
|
||||
const { mixnodes, fetchMixnodes } = useMainContext();
|
||||
const [filteredMixnodes, setFilteredMixnodes] = React.useState<MixNodeResponse>([]);
|
||||
const [pageSize, setPageSize] = React.useState<string>('10');
|
||||
|
||||
@@ -10,7 +10,7 @@ import { WorldMap } from '../../components/WorldMap';
|
||||
import { useMainContext } from '../../context/main';
|
||||
import { CountryDataRowType, countryDataToGridRow } from '../../utils';
|
||||
|
||||
export const PageMixnodesMap: React.FC = () => {
|
||||
export const PageMixnodesMap: FCWithChildren = () => {
|
||||
const { countryData } = useMainContext();
|
||||
const [pageSize, setPageSize] = React.useState<string>('10');
|
||||
const [formattedCountries, setFormattedCountries] = React.useState<CountryDataRowType[]>([]);
|
||||
@@ -115,5 +115,10 @@ export const PageMixnodesMap: React.FC = () => {
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
return <Alert severity="error">{countryData?.error}</Alert>;
|
||||
|
||||
if (countryData?.error) {
|
||||
return <Alert severity="error">{countryData.error.message}</Alert>;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
@@ -15,7 +15,7 @@ import { ContentCard } from '../../components/ContentCard';
|
||||
import { StatsCard } from '../../components/StatsCard';
|
||||
import { Icons } from '../../components/Icons';
|
||||
|
||||
export const PageOverview: React.FC = () => {
|
||||
export const PageOverview: FCWithChildren = () => {
|
||||
const theme = useTheme();
|
||||
const navigate = useNavigate();
|
||||
const { summaryOverview, gateways, validators, block, countryData } = useMainContext();
|
||||
|
||||
@@ -5,11 +5,11 @@ import { PageMixnodesMap } from '../pages/MixnodesMap';
|
||||
import { Page404 } from '../pages/404';
|
||||
import { NetworkComponentsRoutes } from './network-components';
|
||||
|
||||
export const Routes: React.FC = () => (
|
||||
export const Routes: FCWithChildren = () => (
|
||||
<ReactRouterRoutes>
|
||||
<Route path="/" element={<PageOverview />} />
|
||||
<Route path="/network-components/*" element={<NetworkComponentsRoutes />} />
|
||||
<Route path="/nodemap" element={<PageMixnodesMap />} />
|
||||
<Route path="*" element={Page404} />
|
||||
<Route path="*" element={<Page404 />} />
|
||||
</ReactRouterRoutes>
|
||||
);
|
||||
|
||||
@@ -6,14 +6,14 @@ import { PageGatewayDetail } from '../pages/GatewayDetail';
|
||||
import { PageMixnodeDetail } from '../pages/MixnodeDetail';
|
||||
import { PageMixnodes } from '../pages/Mixnodes';
|
||||
|
||||
const ValidatorRoute: React.FC = () => {
|
||||
const ValidatorRoute: FCWithChildren = () => {
|
||||
const navigate = useNavigate();
|
||||
window.open(`${BIG_DIPPER}/validators`);
|
||||
navigate(-1);
|
||||
return null;
|
||||
};
|
||||
|
||||
export const NetworkComponentsRoutes: React.FC = () => (
|
||||
export const NetworkComponentsRoutes: FCWithChildren = () => (
|
||||
<ReactRouterRoutes>
|
||||
<Route path="mixnodes/:status" element={<PageMixnodes />} />
|
||||
<Route path="mixnodes" element={<PageMixnodes />} />
|
||||
|
||||
@@ -2,7 +2,7 @@ import * as React from 'react';
|
||||
import { NymNetworkExplorerThemeProvider } from '@nymproject/mui-theme';
|
||||
import { useMainContext } from '../context/main';
|
||||
|
||||
export const NetworkExplorerThemeProvider: React.FC = ({ children }) => {
|
||||
export const NetworkExplorerThemeProvider: FCWithChildren = ({ children }) => {
|
||||
const { mode } = useMainContext();
|
||||
return <NymNetworkExplorerThemeProvider mode={mode}>{children}</NymNetworkExplorerThemeProvider>;
|
||||
};
|
||||
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
declare type FCWithChildren<P = {}> = React.FC<React.PropsWithChildren<P>>;
|
||||
@@ -36,8 +36,8 @@
|
||||
"clsx": "^1.1.1",
|
||||
"luxon": "^2.3.0",
|
||||
"pretty-bytes": "^6.0.0",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-error-boundary": "^3.1.3",
|
||||
"react-hook-form": "^7.14.2",
|
||||
"react-markdown": "^8.0.4",
|
||||
@@ -62,8 +62,8 @@
|
||||
"@types/jest": "^27.0.1",
|
||||
"@types/luxon": "^2.3.2",
|
||||
"@types/node": "^16.7.13",
|
||||
"@types/react": "^17.0.34",
|
||||
"@types/react-dom": "^17.0.9",
|
||||
"@types/react": "^18.0.26",
|
||||
"@types/react-dom": "^18.0.10",
|
||||
"@types/semver": "^7.3.8",
|
||||
"@types/uuid": "^8.3.4",
|
||||
"@typescript-eslint/eslint-plugin": "^5.13.0",
|
||||
|
||||
@@ -8,7 +8,7 @@ import { ConnectedLayout } from './layouts/ConnectedLayout';
|
||||
import { HelpGuideLayout } from './layouts/HelpGuideLayout';
|
||||
import { useTauriEvents } from './utils';
|
||||
|
||||
export const App: React.FC = () => {
|
||||
export const App: FCWithChildren = () => {
|
||||
const context = useClientContext();
|
||||
const [busy, setBusy] = React.useState<boolean>();
|
||||
const [showInfoModal, setShowInfoModal] = React.useState(false);
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Box } from '@mui/material';
|
||||
import { CustomTitleBar } from './CustomTitleBar';
|
||||
import { AppVersion } from './AppVersion';
|
||||
|
||||
export const AppWindowFrame: React.FC = ({ children }) => (
|
||||
export const AppWindowFrame: FCWithChildren = ({ children }) => (
|
||||
<Box
|
||||
sx={{
|
||||
display: 'grid',
|
||||
|
||||
@@ -51,7 +51,7 @@ const getStatusText = (status: ConnectionStatusKind, hover: boolean): string =>
|
||||
}
|
||||
};
|
||||
|
||||
export const ConnectionButton: React.FC<{
|
||||
export const ConnectionButton: FCWithChildren<{
|
||||
status: ConnectionStatusKind;
|
||||
disabled?: boolean;
|
||||
busy?: boolean;
|
||||
|
||||
@@ -10,7 +10,7 @@ export interface ConnectionStatsItem {
|
||||
|
||||
const FONT_SIZE = '14px';
|
||||
|
||||
export const ConnectionStats: React.FC<{
|
||||
export const ConnectionStats: FCWithChildren<{
|
||||
stats: ConnectionStatsItem[];
|
||||
}> = ({ stats }) => (
|
||||
<Box color="rgba(255,255,255,0.6)" width="100%" display="flex" justifyContent="space-between">
|
||||
|
||||
@@ -9,7 +9,7 @@ const FONT_SIZE = '10px';
|
||||
const FONT_WEIGHT = '600';
|
||||
const FONT_STYLE = 'normal';
|
||||
|
||||
const ConnectionStatusContent: React.FC<{
|
||||
const ConnectionStatusContent: FCWithChildren<{
|
||||
status: ConnectionStatusKind;
|
||||
}> = ({ status }) => {
|
||||
switch (status) {
|
||||
@@ -56,7 +56,7 @@ const ConnectionStatusContent: React.FC<{
|
||||
}
|
||||
};
|
||||
|
||||
export const ConnectionStatus: React.FC<{
|
||||
export const ConnectionStatus: FCWithChildren<{
|
||||
status: ConnectionStatusKind;
|
||||
connectedSince?: DateTime;
|
||||
serviceProvider?: ServiceProvider;
|
||||
|
||||
@@ -8,7 +8,7 @@ import { useTestAndEarnContext } from './context/TestAndEarnContext';
|
||||
import { NymShipyardTheme } from '../../theme';
|
||||
import { ConnectionStatusKind } from '../../types';
|
||||
|
||||
export const Wrapper: React.FC<{ disabled: boolean }> = ({ disabled, children }) => {
|
||||
export const Wrapper: FCWithChildren<{ disabled: boolean }> = ({ disabled, children }) => {
|
||||
if (disabled) {
|
||||
return (
|
||||
<Badge badgeContent="!" color="warning">
|
||||
@@ -21,7 +21,7 @@ export const Wrapper: React.FC<{ disabled: boolean }> = ({ disabled, children })
|
||||
return <>{children}</>;
|
||||
};
|
||||
|
||||
export const TestAndEarnButtonArea: React.FC = () => {
|
||||
export const TestAndEarnButtonArea: FCWithChildren = () => {
|
||||
const clientContext = useClientContext();
|
||||
const context = useTestAndEarnContext();
|
||||
const disabled = clientContext.connectionStatus !== ConnectionStatusKind.connected;
|
||||
|
||||
@@ -10,7 +10,7 @@ import { useTestAndEarnContext } from './context/TestAndEarnContext';
|
||||
import { DrawEntryStatus, DrawWithWordOfTheDay } from './context/types';
|
||||
import Content from './content/en.yaml';
|
||||
|
||||
export const TestAndEarnCurrentDrawFuture: React.FC<{ draw?: DrawWithWordOfTheDay }> = ({ draw }) => {
|
||||
export const TestAndEarnCurrentDrawFuture: FCWithChildren<{ draw?: DrawWithWordOfTheDay }> = ({ draw }) => {
|
||||
const startsUtc = React.useMemo(() => draw && DateTime.fromISO(draw.start_utc), [draw?.start_utc]);
|
||||
const startsIn = React.useMemo(() => {
|
||||
if (draw && startsUtc) {
|
||||
@@ -34,7 +34,7 @@ export const TestAndEarnCurrentDrawFuture: React.FC<{ draw?: DrawWithWordOfTheDa
|
||||
);
|
||||
};
|
||||
|
||||
export const TestAndEarnCurrentDrawEnter: React.FC<{ draw?: DrawWithWordOfTheDay }> = ({ draw }) => {
|
||||
export const TestAndEarnCurrentDrawEnter: FCWithChildren<{ draw?: DrawWithWordOfTheDay }> = ({ draw }) => {
|
||||
const context = useTestAndEarnContext();
|
||||
const [busy, setBusy] = React.useState(false);
|
||||
const [error, setError] = React.useState<string>();
|
||||
@@ -72,7 +72,7 @@ export const TestAndEarnCurrentDrawEnter: React.FC<{ draw?: DrawWithWordOfTheDay
|
||||
);
|
||||
};
|
||||
|
||||
export const TestAndEarnCurrentDrawEntered: React.FC<{ draw?: DrawWithWordOfTheDay }> = ({ draw }) => {
|
||||
export const TestAndEarnCurrentDrawEntered: FCWithChildren<{ draw?: DrawWithWordOfTheDay }> = ({ draw }) => {
|
||||
if (!draw || !draw.entry) {
|
||||
return null;
|
||||
}
|
||||
@@ -131,7 +131,7 @@ export const TestAndEarnCurrentDrawEntered: React.FC<{ draw?: DrawWithWordOfTheD
|
||||
);
|
||||
};
|
||||
|
||||
export const TestAndEarnCurrentDraw: React.FC<{
|
||||
export const TestAndEarnCurrentDraw: FCWithChildren<{
|
||||
draw?: DrawWithWordOfTheDay;
|
||||
sx?: SxProps;
|
||||
}> = ({ draw, sx }) => {
|
||||
@@ -171,7 +171,7 @@ export const TestAndEarnCurrentDraw: React.FC<{
|
||||
return null;
|
||||
};
|
||||
|
||||
export const TestAndEarnCurrentDrawWithState: React.FC<{
|
||||
export const TestAndEarnCurrentDrawWithState: FCWithChildren<{
|
||||
sx?: SxProps;
|
||||
}> = ({ sx }) => {
|
||||
const context = useTestAndEarnContext();
|
||||
|
||||
@@ -39,7 +39,7 @@ const statusToColor = (status: string): 'info' | 'success' | 'warning' | undefin
|
||||
}
|
||||
};
|
||||
|
||||
const StatusText: React.FC<{ entry: DrawEntry }> = ({ entry }) => {
|
||||
const StatusText: FCWithChildren<{ entry: DrawEntry }> = ({ entry }) => {
|
||||
const context = useTestAndEarnContext();
|
||||
const [busy, setBusy] = React.useState(false);
|
||||
const [error, setError] = React.useState<string>();
|
||||
@@ -132,7 +132,7 @@ const StatusText: React.FC<{ entry: DrawEntry }> = ({ entry }) => {
|
||||
}
|
||||
};
|
||||
|
||||
export const TestAndEarnDraws: React.FC<{
|
||||
export const TestAndEarnDraws: FCWithChildren<{
|
||||
sx?: SxProps;
|
||||
}> = ({ sx }) => {
|
||||
const context = useTestAndEarnContext();
|
||||
@@ -181,7 +181,7 @@ export const TestAndEarnDraws: React.FC<{
|
||||
);
|
||||
};
|
||||
|
||||
export const TestAndEarnDrawsWithState: React.FC<{
|
||||
export const TestAndEarnDrawsWithState: FCWithChildren<{
|
||||
sx?: SxProps;
|
||||
}> = ({ sx }) => {
|
||||
const context = useTestAndEarnContext();
|
||||
|
||||
@@ -5,7 +5,7 @@ import { Paper, Stack, Button, Box } from '@mui/material';
|
||||
import ArrowCircleRightIcon from '@mui/icons-material/ArrowCircleRight';
|
||||
import { useTestAndEarnContext } from './context/TestAndEarnContext';
|
||||
|
||||
export const TestAndEarnEnterWalletAddress: React.FC<{
|
||||
export const TestAndEarnEnterWalletAddress: FCWithChildren<{
|
||||
initialValue?: string;
|
||||
placeholder?: string;
|
||||
onSubmit?: () => Promise<void> | void;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { Box, Button } from '@mui/material';
|
||||
|
||||
export const TestAndEarnError: React.FC<{ error?: string }> = ({ error = 'An error has occurred' }) => (
|
||||
export const TestAndEarnError: FCWithChildren<{ error?: string }> = ({ error = 'An error has occurred' }) => (
|
||||
<Box>
|
||||
<Box mb={4} fontWeight="bold">
|
||||
{error}
|
||||
|
||||
@@ -29,12 +29,12 @@ export default {
|
||||
component: TestAndEarnPopupContent,
|
||||
} as ComponentMeta<typeof TestAndEarnPopupContent>;
|
||||
|
||||
const MacOSWindow: React.FC<{ width?: string | number; height?: string | number; title?: string }> = ({
|
||||
title,
|
||||
width,
|
||||
height,
|
||||
children,
|
||||
}) => (
|
||||
const MacOSWindow: FCWithChildren<{
|
||||
width?: string | number;
|
||||
height?: string | number;
|
||||
title?: string;
|
||||
children: React.ReactNode;
|
||||
}> = ({ title, width, height, children }) => (
|
||||
<Box sx={{ border: '1px solid #EEEEEE', width, height }}>
|
||||
<Box sx={{ background: '#EEEEEE', display: 'grid', gridTemplateColumns: 'auto auto', gridTemplateRows: 'auto' }}>
|
||||
<Box ml={1}>
|
||||
@@ -67,7 +67,7 @@ const MacOSWindow: React.FC<{ width?: string | number; height?: string | number;
|
||||
</Box>
|
||||
);
|
||||
|
||||
const Wrapper: React.FC<{ text: React.ReactNode }> = ({ text }) => (
|
||||
const Wrapper: FCWithChildren<{ text: React.ReactNode }> = ({ text }) => (
|
||||
<NymShipyardTheme>
|
||||
<Alert severity="info" sx={{ mb: 4 }}>
|
||||
{text}
|
||||
|
||||
@@ -15,7 +15,7 @@ enum Stages {
|
||||
registered = 'registered',
|
||||
}
|
||||
|
||||
export const TestAndEarnPopupContent: React.FC<{
|
||||
export const TestAndEarnPopupContent: FCWithChildren<{
|
||||
stage?: string;
|
||||
connectionStatus?: ConnectionStatusKind;
|
||||
error?: string;
|
||||
@@ -72,7 +72,7 @@ export const TestAndEarnPopupContent: React.FC<{
|
||||
}
|
||||
};
|
||||
|
||||
export const TestAndEarnPopup: React.FC = () => {
|
||||
export const TestAndEarnPopup: FCWithChildren = () => {
|
||||
const clientContext = useClientContext();
|
||||
const context = useTestAndEarnContext();
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import { invoke } from '@tauri-apps/api';
|
||||
import { useTestAndEarnContext } from './context/TestAndEarnContext';
|
||||
import { ClientId, Registration } from './context/types';
|
||||
|
||||
export const TestAndEarnTakePart: React.FC<{
|
||||
export const TestAndEarnTakePart: FCWithChildren<{
|
||||
websiteLinkUrl: string;
|
||||
websiteLinkText: string;
|
||||
content: string;
|
||||
|
||||
@@ -8,7 +8,7 @@ import { DrawEntry, DrawEntryStatus } from './context/types';
|
||||
import { TestAndEarnEnterWalletAddress } from './TestAndEarnEnterWalletAddress';
|
||||
import Content from './content/en.yaml';
|
||||
|
||||
export const TestAndEarnWinner: React.FC<{
|
||||
export const TestAndEarnWinner: FCWithChildren<{
|
||||
sx?: SxProps;
|
||||
entry?: DrawEntry;
|
||||
}> = ({ sx, entry }) => {
|
||||
@@ -100,7 +100,7 @@ export const TestAndEarnWinner: React.FC<{
|
||||
);
|
||||
};
|
||||
|
||||
export const TestAndEarnWinnerWithState: React.FC<{
|
||||
export const TestAndEarnWinnerWithState: FCWithChildren<{
|
||||
sx?: SxProps;
|
||||
}> = ({ sx }) => {
|
||||
const context = useTestAndEarnContext();
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Box, Button, Card, CardContent, CardMedia, Typography } from '@mui/mate
|
||||
import { SxProps } from '@mui/system';
|
||||
import Content from './content/TestAndEarn/WinnerEntersWalletAddress.mdx';
|
||||
|
||||
export const TestAndEarnWinnerWalletAddress: React.FC<{
|
||||
export const TestAndEarnWinnerWalletAddress: FCWithChildren<{
|
||||
sx?: SxProps;
|
||||
}> = ({ sx }) => (
|
||||
<Box>
|
||||
|
||||
@@ -44,7 +44,7 @@ export const TestAndEarnContext = createContext(defaultValue);
|
||||
const CLIENT_ID_KEY = 'tne_client_id';
|
||||
const REGISTRATION_KEY = 'tne_registration';
|
||||
|
||||
export const TestAndEarnContextProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
export const TestAndEarnContextProvider: FCWithChildren = ({ children }) => {
|
||||
const clientContext = useClientContext();
|
||||
const [loadedOnce, setLoadedOnce] = useState(false);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
@@ -21,7 +21,7 @@ const mockValues_NotRegistered: TTestAndEarnContext = {
|
||||
...methodDefaults,
|
||||
};
|
||||
|
||||
export const MockTestAndEarnProvider_NotRegistered = ({ children }: { children: React.ReactNode }) => (
|
||||
export const MockTestAndEarnProvider_NotRegistered: FCWithChildren = ({ children }) => (
|
||||
<TestAndEarnContext.Provider value={mockValues_NotRegistered}>{children}</TestAndEarnContext.Provider>
|
||||
);
|
||||
|
||||
@@ -43,7 +43,7 @@ const mockValues_Registered: TTestAndEarnContext = {
|
||||
},
|
||||
};
|
||||
|
||||
export const MockTestAndEarnProvider_Registered = ({ children }: { children: React.ReactNode }) => (
|
||||
export const MockTestAndEarnProvider_Registered: FCWithChildren = ({ children }) => (
|
||||
<TestAndEarnContext.Provider value={mockValues_Registered}>{children}</TestAndEarnContext.Provider>
|
||||
);
|
||||
|
||||
@@ -137,7 +137,7 @@ const mockValues_RegisteredWithAllDrawsAndEntry: TTestAndEarnContext = {
|
||||
},
|
||||
};
|
||||
|
||||
export const MockTestAndEarnProvider_RegisteredWithAllDraws = ({ children }: { children: React.ReactNode }) => (
|
||||
export const MockTestAndEarnProvider_RegisteredWithAllDraws: FCWithChildren = ({ children }) => (
|
||||
<TestAndEarnContext.Provider value={mockValues_RegisteredWithAllDrawsAndEntry}>
|
||||
{children}
|
||||
</TestAndEarnContext.Provider>
|
||||
@@ -150,7 +150,7 @@ const mockValues_RegisteredWithDrawsNoCurrent: TTestAndEarnContext = {
|
||||
},
|
||||
};
|
||||
|
||||
export const MockTestAndEarnProvider_RegisteredWithDrawsNoCurrent = ({ children }: { children: React.ReactNode }) => (
|
||||
export const MockTestAndEarnProvider_RegisteredWithDrawsNoCurrent: FCWithChildren = ({ children }) => (
|
||||
<TestAndEarnContext.Provider value={mockValues_RegisteredWithDrawsNoCurrent}>{children}</TestAndEarnContext.Provider>
|
||||
);
|
||||
|
||||
@@ -162,7 +162,7 @@ const mockValues_RegisteredWithDraws: TTestAndEarnContext = {
|
||||
},
|
||||
};
|
||||
|
||||
export const MockTestAndEarnProvider_RegisteredWithDraws = ({ children }: { children: React.ReactNode }) => (
|
||||
export const MockTestAndEarnProvider_RegisteredWithDraws: FCWithChildren = ({ children }) => (
|
||||
<TestAndEarnContext.Provider value={mockValues_RegisteredWithDraws}>{children}</TestAndEarnContext.Provider>
|
||||
);
|
||||
|
||||
@@ -177,7 +177,7 @@ const mockValues_RegisteredWithDrawsAndEntry: TTestAndEarnContext = {
|
||||
},
|
||||
};
|
||||
|
||||
export const MockTestAndEarnProvider_RegisteredWithDrawsAndEntry = ({ children }: { children: React.ReactNode }) => (
|
||||
export const MockTestAndEarnProvider_RegisteredWithDrawsAndEntry: FCWithChildren = ({ children }) => (
|
||||
<TestAndEarnContext.Provider value={mockValues_RegisteredWithDrawsAndEntry}>{children}</TestAndEarnContext.Provider>
|
||||
);
|
||||
|
||||
@@ -257,6 +257,6 @@ const mockValues_RegisteredAndError: TTestAndEarnContext = {
|
||||
error: 'Error message text will go here',
|
||||
};
|
||||
|
||||
export const MockTestAndEarnProvider_RegisteredAndError = ({ children }: { children: React.ReactNode }) => (
|
||||
export const MockTestAndEarnProvider_RegisteredAndError: FCWithChildren = ({ children }) => (
|
||||
<TestAndEarnContext.Provider value={mockValues_RegisteredAndError}>{children}</TestAndEarnContext.Provider>
|
||||
);
|
||||
|
||||
@@ -14,7 +14,7 @@ const IpAddressAndPortContainer = styled('div')({
|
||||
},
|
||||
});
|
||||
|
||||
export const IpAddressAndPort: React.FC<{
|
||||
export const IpAddressAndPort: FCWithChildren<{
|
||||
label: string;
|
||||
ipAddress: string;
|
||||
port: number;
|
||||
|
||||
@@ -4,7 +4,7 @@ import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
|
||||
|
||||
const HELP_URL = 'https://docs.nymtech.net';
|
||||
|
||||
export const NeedHelp: React.FC = () => (
|
||||
export const NeedHelp: FCWithChildren = () => (
|
||||
<Box sx={{ display: 'grid', placeItems: 'center' }}>
|
||||
<Button component="a" href={HELP_URL} target="_blank" sx={{ fontSize: '12px', fontWeight: '600' }} color="info">
|
||||
<HelpOutlineIcon color="inherit" fontSize="inherit" fontWeight="inherit" />
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
import { Autocomplete, Box, Chip, Dialog, DialogProps, TextField, Typography } from '@mui/material';
|
||||
import { ServiceProvider, Service, Services } from '../types/directory';
|
||||
|
||||
export const ServiceProviderPopup: React.FC<
|
||||
export const ServiceProviderPopup: FCWithChildren<
|
||||
DialogProps & { services: Services; onServiceProviderChanged: (sp?: ServiceProvider, s?: Service) => void }
|
||||
> = ({ services, onServiceProviderChanged, ...dialogProps }) => {
|
||||
const options = services.flatMap((s) =>
|
||||
|
||||
@@ -11,7 +11,7 @@ type ServiceWithRandomSp = {
|
||||
|
||||
const defaultServiceValue = { id: '', description: '', items: [] };
|
||||
|
||||
export const ServiceProviderSelector: React.FC<{
|
||||
export const ServiceProviderSelector: FCWithChildren<{
|
||||
onChange?: (serviceProvider?: ServiceProvider) => void;
|
||||
services?: Services;
|
||||
currentSp?: ServiceProvider;
|
||||
|
||||
@@ -14,7 +14,7 @@ import { Service, ServiceProvider, Services } from '../types/directory';
|
||||
import { useTauriEvents } from '../utils';
|
||||
import { ServiceProviderPopup } from './ServiceProviderPopup';
|
||||
|
||||
export const ServiceSelector: React.FC<{
|
||||
export const ServiceSelector: FCWithChildren<{
|
||||
onChange?: (serviceProvider?: ServiceProvider) => void;
|
||||
services?: Services;
|
||||
currentSp?: ServiceProvider;
|
||||
|
||||
@@ -40,7 +40,7 @@ export type TClientContext = {
|
||||
|
||||
export const ClientContext = createContext({} as TClientContext);
|
||||
|
||||
export const ClientContextProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
export const ClientContextProvider: FCWithChildren = ({ children }) => {
|
||||
const [mode, setMode] = useState<ModeType>('dark');
|
||||
const [connectionStatus, setConnectionStatus] = useState<ConnectionStatusKind>(ConnectionStatusKind.disconnected);
|
||||
const [connectionStats, setConnectionStats] = useState<ConnectionStatsItem[]>();
|
||||
|
||||
@@ -20,7 +20,7 @@ const mockValues: TClientContext = {
|
||||
startDisconnecting: async () => {},
|
||||
};
|
||||
|
||||
export const MockProvider: React.FC<{
|
||||
export const MockProvider: FCWithChildren<{
|
||||
children?: React.ReactNode;
|
||||
connectionStatus?: ConnectionStatusKind;
|
||||
}> = ({ connectionStatus = ConnectionStatusKind.disconnected, children }) => (
|
||||
|
||||
+18
-16
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
import { ErrorBoundary } from 'react-error-boundary';
|
||||
import { ClientContextProvider } from './context/main';
|
||||
import { ErrorFallback } from './components/Error';
|
||||
@@ -8,19 +8,21 @@ import { App } from './App';
|
||||
import { AppWindowFrame } from './components/AppWindowFrame';
|
||||
import { TestAndEarnContextProvider } from './components/Growth/context/TestAndEarnContext';
|
||||
|
||||
const root = document.getElementById('root');
|
||||
const elem = document.getElementById('root');
|
||||
|
||||
ReactDOM.render(
|
||||
<ErrorBoundary FallbackComponent={ErrorFallback}>
|
||||
<ClientContextProvider>
|
||||
<TestAndEarnContextProvider>
|
||||
<NymMixnetTheme mode="dark">
|
||||
<AppWindowFrame>
|
||||
<App />
|
||||
</AppWindowFrame>
|
||||
</NymMixnetTheme>
|
||||
</TestAndEarnContextProvider>
|
||||
</ClientContextProvider>
|
||||
</ErrorBoundary>,
|
||||
root,
|
||||
);
|
||||
if (elem) {
|
||||
const root = createRoot(elem);
|
||||
root.render(
|
||||
<ErrorBoundary FallbackComponent={ErrorFallback}>
|
||||
<ClientContextProvider>
|
||||
<TestAndEarnContextProvider>
|
||||
<NymMixnetTheme mode="dark">
|
||||
<AppWindowFrame>
|
||||
<App />
|
||||
</AppWindowFrame>
|
||||
</NymMixnetTheme>
|
||||
</TestAndEarnContextProvider>
|
||||
</ClientContextProvider>
|
||||
</ErrorBoundary>,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import { IpAddressAndPort } from '../components/IpAddressAndPort';
|
||||
import { ServiceProvider } from '../types/directory';
|
||||
import { TestAndEarnButtonArea } from '../components/Growth/TestAndEarnButtonArea';
|
||||
|
||||
export const ConnectedLayout: React.FC<{
|
||||
export const ConnectedLayout: FCWithChildren<{
|
||||
status: ConnectionStatusKind;
|
||||
stats: ConnectionStatsItem[];
|
||||
ipAddress: string;
|
||||
|
||||
@@ -12,7 +12,7 @@ import { Services } from '../types/directory';
|
||||
import { TestAndEarnButtonArea } from '../components/Growth/TestAndEarnButtonArea';
|
||||
import { AppVersion } from '../components/AppVersion';
|
||||
|
||||
export const DefaultLayout: React.FC<{
|
||||
export const DefaultLayout: FCWithChildren<{
|
||||
error?: Error;
|
||||
status: ConnectionStatusKind;
|
||||
services?: Services;
|
||||
|
||||
@@ -7,7 +7,7 @@ import '../../../assets/fonts/non-variable/fonts.css';
|
||||
/**
|
||||
* Provides the theme for Nym Connect by reacting to the light/dark mode choice stored in the app context.
|
||||
*/
|
||||
export const NymMixnetTheme: React.FC<{ mode: 'light' | 'dark' }> = ({ children, mode }) => {
|
||||
export const NymMixnetTheme: FCWithChildren<{ mode: 'light' | 'dark' }> = ({ children, mode }) => {
|
||||
const theme = React.useMemo(() => createTheme(getDesignTokens(mode)), [mode]);
|
||||
return (
|
||||
<ThemeProvider theme={theme}>
|
||||
@@ -17,7 +17,7 @@ export const NymMixnetTheme: React.FC<{ mode: 'light' | 'dark' }> = ({ children,
|
||||
);
|
||||
};
|
||||
|
||||
export const NymShipyardTheme: React.FC<{ mode?: 'light' | 'dark' }> = ({ children, mode = 'dark' }) => {
|
||||
export const NymShipyardTheme: FCWithChildren<{ mode?: 'light' | 'dark' }> = ({ children, mode = 'dark' }) => {
|
||||
const theme = React.useMemo(() => createTheme(getDesignTokens(mode, true)), [mode]);
|
||||
return (
|
||||
<ThemeProvider theme={theme}>
|
||||
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
declare type FCWithChildren<P = {}> = React.FC<React.PropsWithChildren<P>>;
|
||||
@@ -42,8 +42,8 @@
|
||||
"notistack": "^2.0.3",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"qrcode.react": "^1.0.1",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-error-boundary": "^3.1.3",
|
||||
"react-hook-form": "^7.14.2",
|
||||
"react-router-dom": "6",
|
||||
@@ -72,8 +72,8 @@
|
||||
"@types/jest": "^27.0.1",
|
||||
"@types/node": "^16.7.13",
|
||||
"@types/qrcode.react": "^1.0.2",
|
||||
"@types/react": "^17.0.34",
|
||||
"@types/react-dom": "^17.0.9",
|
||||
"@types/react": "^18.0.26",
|
||||
"@types/react-dom": "^18.0.10",
|
||||
"@types/semver": "^7.3.8",
|
||||
"@types/uuid": "^8.3.4",
|
||||
"@typescript-eslint/eslint-plugin": "^5.13.0",
|
||||
|
||||
@@ -2,12 +2,12 @@ import React, { useRef } from 'react';
|
||||
import { MoreVertSharp } from '@mui/icons-material';
|
||||
import { IconButton, ListItemIcon, ListItemText, Menu, MenuItem } from '@mui/material';
|
||||
|
||||
export const ActionsMenu: React.FC<{ open: boolean; onOpen: () => void; onClose: () => void }> = ({
|
||||
children,
|
||||
open,
|
||||
onOpen,
|
||||
onClose,
|
||||
}) => {
|
||||
export const ActionsMenu: FCWithChildren<{
|
||||
open: boolean;
|
||||
children: React.ReactNode;
|
||||
onOpen: () => void;
|
||||
onClose: () => void;
|
||||
}> = ({ children, open, onOpen, onClose }) => {
|
||||
const anchorEl: any = useRef<HTMLElement>();
|
||||
|
||||
return (
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
import { Stack, Typography } from '@mui/material';
|
||||
import { SimpleModal } from 'src/components/Modals/SimpleModal';
|
||||
|
||||
export const BondOversaturatedModal: React.FC<{
|
||||
export const BondOversaturatedModal: FCWithChildren<{
|
||||
open: boolean;
|
||||
saturationPercentage: string;
|
||||
onClose?: () => void;
|
||||
|
||||
@@ -4,20 +4,14 @@ import { AppContext } from '../context/main';
|
||||
import { CopyToClipboard } from './CopyToClipboard';
|
||||
import { splice } from '../utils';
|
||||
|
||||
const AddressTooltip: FC<{ visible?: boolean; address?: string; children: React.ReactElement<any, any> }> = ({
|
||||
visible,
|
||||
address,
|
||||
children,
|
||||
}) => {
|
||||
if (!visible) {
|
||||
return children;
|
||||
}
|
||||
if (!address) {
|
||||
return children;
|
||||
const AddressTooltip: FCWithChildren<{ visible?: boolean; address?: string }> = ({ visible, address, children }) => {
|
||||
if (!visible || !address) {
|
||||
return <>{children}</>;
|
||||
}
|
||||
|
||||
return (
|
||||
<Tooltip title={address} arrow>
|
||||
{children}
|
||||
<>{children}</>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -15,7 +15,7 @@ const storybookStyles = (theme: Theme, isStorybook?: boolean, backdropProps?: ob
|
||||
}
|
||||
: {};
|
||||
|
||||
export const ConfirmTx: React.FC<{
|
||||
export const ConfirmTx: FCWithChildren<{
|
||||
open: boolean;
|
||||
header: string;
|
||||
subheader?: string;
|
||||
@@ -24,6 +24,7 @@ export const ConfirmTx: React.FC<{
|
||||
onClose?: () => void;
|
||||
onPrev: () => void;
|
||||
isStorybook?: boolean;
|
||||
children?: React.ReactNode;
|
||||
}> = ({ open, fee, onConfirm, onClose, header, subheader, onPrev, children, isStorybook }) => {
|
||||
const theme = useTheme();
|
||||
return (
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
import { SxProps } from '@mui/material';
|
||||
import { SimpleModal } from '../Modals/SimpleModal';
|
||||
|
||||
export const OverSaturatedBlockerModal: React.FC<{
|
||||
export const OverSaturatedBlockerModal: FCWithChildren<{
|
||||
open: boolean;
|
||||
onClose?: () => void;
|
||||
header?: string;
|
||||
|
||||
@@ -18,7 +18,7 @@ import { ErrorModal } from '../Modals/ErrorModal';
|
||||
|
||||
const MIN_AMOUNT_TO_DELEGATE = 10;
|
||||
|
||||
export const DelegateModal: React.FC<{
|
||||
export const DelegateModal: FCWithChildren<{
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
onOk?: (
|
||||
|
||||
@@ -10,7 +10,7 @@ export type DelegationListItemActions = 'delegate' | 'undelegate' | 'redeem' | '
|
||||
const BUTTON_SIZE = '32px';
|
||||
const MIN_WIDTH = '150px';
|
||||
|
||||
export const DelegationActions: React.FC<{
|
||||
export const DelegationActions: FCWithChildren<{
|
||||
onActionClick?: (action: DelegationListItemActions) => void;
|
||||
isPending?: DelegateListItemPending;
|
||||
disableRedeemingRewards?: boolean;
|
||||
@@ -64,7 +64,7 @@ export const DelegationActions: React.FC<{
|
||||
);
|
||||
};
|
||||
|
||||
export const DelegationsActionsMenu: React.FC<{
|
||||
export const DelegationsActionsMenu: FCWithChildren<{
|
||||
onActionClick?: (action: DelegationListItemActions) => void;
|
||||
disableRedeemingRewards?: boolean;
|
||||
disableDelegateMore?: boolean | null;
|
||||
|
||||
@@ -45,7 +45,7 @@ const headCells: HeadCell[] = [
|
||||
{ id: 'unclaimed_rewards', label: 'Reward', sortable: true, align: 'left' },
|
||||
];
|
||||
|
||||
const EnhancedTableHead: React.FC<EnhancedTableProps> = ({ order, orderBy, onRequestSort }) => {
|
||||
const EnhancedTableHead: FCWithChildren<EnhancedTableProps> = ({ order, orderBy, onRequestSort }) => {
|
||||
const createSortHandler = (property: string) => (event: React.MouseEvent<unknown>) => {
|
||||
onRequestSort(event, property);
|
||||
};
|
||||
@@ -87,7 +87,7 @@ const sortByUnbondedMixnodeFirst = (a: DelegationWithEvent) => {
|
||||
return 1;
|
||||
};
|
||||
|
||||
export const DelegationList: React.FC<{
|
||||
export const DelegationList: FCWithChildren<{
|
||||
isLoading?: boolean;
|
||||
items: TDelegations;
|
||||
onItemActionClick?: (item: DelegationWithEverything, action: DelegationListItemActions) => void;
|
||||
|
||||
@@ -30,7 +30,7 @@ const transactionForDarkTheme = {
|
||||
hash: '11ED7B9E21534A9421834F52FED5103DC6E982949C06335F5E12EFC71DAF0CF0',
|
||||
};
|
||||
|
||||
const Content: React.FC<{ children: React.ReactElement<any, any>; handleClick: () => void }> = ({
|
||||
const Content: FCWithChildren<{ children: React.ReactElement<any, any>; handleClick: () => void }> = ({
|
||||
children,
|
||||
handleClick,
|
||||
}) => (
|
||||
|
||||
@@ -36,12 +36,13 @@ export type DelegationModalProps = {
|
||||
}[];
|
||||
};
|
||||
|
||||
export const DelegationModal: React.FC<
|
||||
export const DelegationModal: FCWithChildren<
|
||||
DelegationModalProps & {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
sx?: SxProps;
|
||||
backdropProps?: object;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
> = ({ status, action, message, transactions, open, onClose, children, sx, backdropProps }) => {
|
||||
if (status === 'loading') return <LoadingModal sx={sx} backdropProps={backdropProps} />;
|
||||
|
||||
@@ -5,7 +5,7 @@ import { Link } from '@nymproject/react/link/Link';
|
||||
import { DelegationList } from './DelegationList';
|
||||
import { DelegationListItemActions } from './DelegationActions';
|
||||
|
||||
export const Delegations: React.FC<{
|
||||
export const Delegations: FCWithChildren<{
|
||||
isLoading?: boolean;
|
||||
items: DelegationWithEverything[];
|
||||
explorerUrl: string;
|
||||
|
||||
@@ -15,7 +15,7 @@ export default {
|
||||
title: 'Delegation/Components/Action Modals',
|
||||
};
|
||||
|
||||
const Background: React.FC<{ onOpen: () => void }> = ({ onOpen }) => {
|
||||
const Background: FCWithChildren<{ onOpen: () => void }> = ({ onOpen }) => {
|
||||
const theme = useTheme();
|
||||
return (
|
||||
<Paper elevation={0} sx={{ px: 4, pt: 2, pb: 4 }}>
|
||||
|
||||
@@ -8,7 +8,7 @@ import { ModalFee } from '../Modals/ModalFee';
|
||||
import { ModalListItem } from '../Modals/ModalListItem';
|
||||
import { SimpleModal } from '../Modals/SimpleModal';
|
||||
|
||||
export const UndelegateModal: React.FC<{
|
||||
export const UndelegateModal: FCWithChildren<{
|
||||
open: boolean;
|
||||
onClose?: () => void;
|
||||
onOk?: (mixId: number, identityKey: string, usesVestingContractTokens: boolean, fee?: FeeDetails) => void;
|
||||
|
||||
@@ -2,13 +2,14 @@ import React from 'react';
|
||||
import { Box, Button, Modal, SxProps, Typography } from '@mui/material';
|
||||
import { modalStyle } from './styles';
|
||||
|
||||
export const ErrorModal: React.FC<{
|
||||
export const ErrorModal: FCWithChildren<{
|
||||
open: boolean;
|
||||
title?: string;
|
||||
message?: string;
|
||||
sx?: SxProps;
|
||||
backdropProps?: object;
|
||||
onClose: () => void;
|
||||
children?: React.ReactNode;
|
||||
}> = ({ children, open, title, message, sx, backdropProps, onClose }) => (
|
||||
<Modal open={open} onClose={onClose} BackdropProps={backdropProps}>
|
||||
<Box
|
||||
|
||||
@@ -13,7 +13,7 @@ const modalStyle: SxProps = {
|
||||
p: 4,
|
||||
};
|
||||
|
||||
export const LoadingModal: React.FC<{
|
||||
export const LoadingModal: FCWithChildren<{
|
||||
sx?: SxProps;
|
||||
backdropProps?: object;
|
||||
}> = ({ sx, backdropProps }) => (
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import { Box, SxProps } from '@mui/material';
|
||||
|
||||
export const ModalDivider: React.FC<{
|
||||
export const ModalDivider: FCWithChildren<{
|
||||
sx?: SxProps;
|
||||
}> = ({ sx }) => <Box borderTop="1px solid" borderColor="rgba(141, 147, 153, 0.2)" my={1} sx={sx} />;
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
import { Box, Stack, Typography, TypographyProps } from '@mui/material';
|
||||
import { ModalDivider } from './ModalDivider';
|
||||
|
||||
export const ModalListItem: React.FC<{
|
||||
export const ModalListItem: FCWithChildren<{
|
||||
label: string;
|
||||
divider?: boolean;
|
||||
hidden?: boolean;
|
||||
|
||||
@@ -16,7 +16,7 @@ export default {
|
||||
component: SimpleModal,
|
||||
} as ComponentMeta<typeof SimpleModal>;
|
||||
|
||||
const BasePage: React.FC<{ children: React.ReactElement<any, any>; handleClick: () => void }> = ({
|
||||
const BasePage: FCWithChildren<{ children: React.ReactElement<any, any>; handleClick: () => void }> = ({
|
||||
children,
|
||||
handleClick,
|
||||
}) => (
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user