Skip to content

Commit

Permalink
feat: added wip for new structure
Browse files Browse the repository at this point in the history
  • Loading branch information
rickimoore committed Mar 4, 2024
1 parent f708999 commit a8b89d4
Show file tree
Hide file tree
Showing 11 changed files with 211 additions and 73 deletions.
133 changes: 85 additions & 48 deletions src/views/InitScreen.tsx → app/Main.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,49 @@
import Typography from '../components/Typography/Typography'
import useLocalStorage from '../hooks/useLocalStorage'
import { useCallback, useEffect, useState } from 'react'
import { useSetRecoilState } from 'recoil'
import { FC, useCallback, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useSetRecoilState } from 'recoil';
import { fetchBeaconVersion, fetchSyncStatus } from '../src/api/beacon';
import { fetchVersion } from '../src/api/lighthouse';
import AppDescription from '../src/components/AppDescription/AppDescription';
import InfoBox, { InfoBoxType } from '../src/components/InfoBox/InfoBox';
import LoadingSpinner from '../src/components/LoadingSpinner/LoadingSpinner';
import RodalModal from '../src/components/RodalModal/RodalModal';
import Typography from '../src/components/Typography/Typography';
import { REQUIRED_VALIDATOR_VERSION } from '../src/constants/constants';
import { AppView, OnboardView } from '../src/constants/enums';
import useLocalStorage from '../src/hooks/useLocalStorage';
import {
activeDevice,
appView,
userName,
onBoardView,
beaconVersionData,
validatorVersionData,
activeDevice,
deviceSettings,
onBoardView,
userName,
validatorAliases,
} from '../recoil/atoms'
import { AppView, OnboardView, UiMode } from '../constants/enums'
import LoadingSpinner from '../components/LoadingSpinner/LoadingSpinner'
import { fetchVersion } from '../api/lighthouse'
import { fetchBeaconVersion, fetchSyncStatus } from '../api/beacon'
import { useTranslation } from 'react-i18next'
import { DeviceKeyStorage, DeviceListStorage, UsernameStorage } from '../types/storage'
import AppDescription from '../components/AppDescription/AppDescription'
import SessionAuthModal from '../components/SessionAuthModal/SessionAuthModal'
import isRequiredVersion from '../utilities/isRequiredVersion'
import { REQUIRED_VALIDATOR_VERSION } from '../constants/constants'
import { DeviceSettings, ValAliases } from '../types'

const InitScreen = () => {
validatorVersionData
} from '../src/recoil/atoms';
import { DeviceSettings, ValAliases } from '../src/types';
import { DeviceKeyStorage, DeviceListStorage, UsernameStorage } from '../src/types/storage';
import formatSemanticVersion from '../utilities/formatSemanticVersion';
import isRequiredVersion from '../utilities/isRequiredVersion';

export interface InitProps {
beaconNodeVersion?: string | undefined
apiTokenPath?: string | undefined
}

const Main:FC<InitProps> = ({beaconNodeVersion, apiTokenPath}) => {
const { t } = useTranslation()
const configError = !beaconNodeVersion || !apiTokenPath
const { major, minor, patch } = REQUIRED_VALIDATOR_VERSION
const vcVersion = beaconNodeVersion ? formatSemanticVersion(beaconNodeVersion as string) : undefined;
const versionError = true
// const isVersion = beaconNodeVersion && isRequiredVersion(beaconNodeVersion, REQUIRED_VALIDATOR_VERSION)
const isVersion = false

console.log(isVersion)



const [isReady, setReady] = useState(false)
const [step, setStep] = useState<number>(0)
const setView = useSetRecoilState(appView)
Expand Down Expand Up @@ -120,34 +138,53 @@ const InitScreen = () => {
[storedDevice],
)

const closeModal = () => {
toggleAuthModal(false)
moveToView(AppView.ONBOARD)
}

useEffect(() => {
if (isReady) return

setAlias(aliases)

if (!storedDevice?.apiToken || !username || !devices) {
moveToView(AppView.ONBOARD)
return
}
setUserName(username)
setDevices(devices)
toggleAuthModal(true)
}, [aliases, storedDevice, devices, username, isReady])
// useEffect(() => {
// if (isReady) return
//
// setAlias(aliases)
//
// if (!storedDevice?.apiToken || !username || !devices) {
// moveToView(AppView.ONBOARD)
// return
// }
// setUserName(username)
// setDevices(devices)
// toggleAuthModal(true)
// }, [aliases, storedDevice, devices, username, isReady])

return (
<div className='relative w-screen h-screen bg-gradient-to-r from-primary to-tertiary'>
<SessionAuthModal
mode={UiMode.LIGHT}
onClose={closeModal}
onSuccess={finishInit}
encryptedToken={storedDevice?.apiToken}
isOpen={isAuthModal}
/>
<RodalModal isVisible={configError}>
<div className="p-6">
<InfoBox type={InfoBoxType.ERROR}>
<div className="space-y-4">
<Typography type="text-caption1" color="text-error">Configuration Error</Typography>
<Typography type="text-caption1">Siren was unable to establish a successful connection to designated...Please review your configuration file and make appropriate adjustments. For additional information refer to the Lighthouse Book.</Typography>
<div className="border-b border-error w-fit cursor-pointer">
<Typography type="text-caption1" color="text-error">Learn about Siren configuration here</Typography>
</div>
</div>
</InfoBox>
</div>
</RodalModal>

{vcVersion && (
<RodalModal isVisible={versionError}>
<div className="p-6">
<InfoBox type={InfoBoxType.WARNING}>
<div className="space-y-4">
{/* <Typography type="text-caption1" color="text-error">Version Requirement Error</Typography> */}
<Typography type="text-caption1">
Lighthouse version {vcVersion.major}.{vcVersion.minor}.{vcVersion.patch} is currently detected. For Siren to function properly, a minimum version of {major}.{minor}.{patch} for Lighthouse is required. Please ensure your Lighthouse version meets or exceeds this requirement before proceeding.
</Typography>
<div className="border-b border-error w-fit cursor-pointer">
<Typography type="text-caption1" color="text-error">Upgrade to latest Lighthouse here</Typography>
</div>
</div>
</InfoBox>
</div>
</RodalModal>
)}
<div className='absolute top-0 left-0 w-full h-full bg-cover bg-lighthouse' />
<div className='absolute top-1/2 -translate-y-1/2 left-1/2 -translate-x-1/2'>
<LoadingSpinner />
Expand Down Expand Up @@ -188,4 +225,4 @@ const InitScreen = () => {
)
}

export default InitScreen
export default Main
26 changes: 26 additions & 0 deletions app/Providers.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
'use client'

import React, { FC, ReactElement } from 'react';
import { QueryClient, QueryClientProvider } from 'react-query';
import { RecoilRoot } from 'recoil';
import 'react-tooltip/dist/react-tooltip.css'
import 'react-toastify/dist/ReactToastify.min.css'
import 'rodal/lib/rodal.css'

const queryClient = new QueryClient()

export interface ProviderProps {
children: ReactElement | ReactElement[]
}

const Providers:FC<ProviderProps> = ({children}) => {
return (
<RecoilRoot>
<QueryClientProvider client={queryClient}>
{children}
</QueryClientProvider>
</RecoilRoot>
)
}

export default Providers
16 changes: 16 additions & 0 deletions app/Wrapper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
'use client'

import React, { FC } from 'react';
import Main, { InitProps } from './Main';
import Providers from './Providers';
import '../src/i18n'

const Wrapper:FC<InitProps> = (props) => {
return (
<Providers>
<Main {...props}/>
</Providers>
)
}

export default Wrapper
24 changes: 24 additions & 0 deletions app/api/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { NextFetchRequestInit } from '../../src/types';
import fetchFromApi from '../../utilities/fetchFromApi';

const validatorUrl = process.env.VALIDATOR_URL;
const beaconUrl = process.env.BEACON_URL;
const apiToken = process.env.API_TOKEN;

export const fetchVersion = async () => {
const response = await fetch(`${validatorUrl}/lighthouse/version`, {
method: 'GET',
headers: {
'Authorization': `Bearer ${apiToken}`,
}
} as NextFetchRequestInit);

if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}

return await response.json();
}

export const fetchBeaconNodeVersion = async () => await fetchFromApi(`${beaconUrl}/eth/v1/node/version`)
export const fetchValidatorAuthKey = async () => await fetchFromApi(`${validatorUrl}/lighthouse/auth`)
21 changes: 21 additions & 0 deletions app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { Metadata } from 'next'

export const metadata: Metadata = {
title: 'Siren',
description: 'User interface built for Lighthouse that connects to a Lighthouse Beacon Node and a Lighthouse Validator Client to monitor performance and display key validator metrics.',
}


export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>
<div id="root">{children}</div>
</body>
</html>
)
}
12 changes: 12 additions & 0 deletions app/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { fetchBeaconNodeVersion, fetchValidatorAuthKey } from './api/config';
import Wrapper from './Wrapper';
import '../src/global.css'

export default async function Page() {
const version = await fetchBeaconNodeVersion()
const apiKey = await fetchValidatorAuthKey()

return (
<Wrapper apiTokenPath={apiKey?.token_path} beaconNodeVersion={version?.data?.version}/>
)
}
14 changes: 7 additions & 7 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import React, { Suspense } from 'react'
import { ToastContainer } from 'react-toastify'
import { useRecoilValue } from 'recoil'
import { appView } from './recoil/atoms'
import Main from '../app/Main'
import AppLoadFallback from './components/Fallback/AppLoadFallback'
import SSELogProvider from './components/SSELogProvider/SSELogProvider'
import { AppView } from './constants/enums'
import { appView } from './recoil/atoms'
import ChangeScreen from './views/ChangeScreen'
import Dashboard from './views/DashBoard/Dashboard'
import Onboard from './views/Onboard/Onboard'
import InitScreen from './views/InitScreen'
import { ToastContainer } from 'react-toastify'
import 'react-toastify/dist/ReactToastify.min.css'
import 'rodal/lib/rodal.css'
import SSELogProvider from './components/SSELogProvider/SSELogProvider'
import SyncPollingWrapper from './wrappers/SyncPollingWrapper'
import ChangeScreen from './views/ChangeScreen'
import AppLoadFallback from './components/Fallback/AppLoadFallback'

function App() {
const view = useRecoilValue(appView)
Expand All @@ -37,7 +37,7 @@ function App() {
case AppView.CHANGE_SCREEN:
return <ChangeScreen />
default:
return <InitScreen />
return <Main />
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/assets/images/spinner.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions src/components/LoadingSpinner/LoadingSpinner.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ReactComponent as IconSpinner } from '../../assets/images/spinner.svg'
import { ReactComponent as IconLogo } from '../../assets/images/lightHouse.svg'
import IconLogo from '../../assets/images/lightHouse.svg'
import IconSpinner from '../../assets/images/spinner.svg'

const LoadingSpinner = () => {
return (
Expand Down
10 changes: 6 additions & 4 deletions src/components/RodalModal/RodalModal.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { UiMode } from '../../constants/enums'
import { FC, ReactElement } from 'react'
import Rodal from 'rodal'
import useUiMode from '../../hooks/useUiMode'
import { UiMode } from '../../constants/enums'
import useMediaQuery from '../../hooks/useMediaQuery'
import useUiMode from '../../hooks/useUiMode'

export interface RodalModalProps {
children: ReactElement | ReactElement[]
Expand All @@ -21,10 +21,12 @@ export interface RodalModalProps {
}

const RodalModal: FC<RodalModalProps> = ({ children, isVisible, uiMode, onClose, styles }) => {
const { mode } = uiMode || useUiMode()
const { mode } = useUiMode()

const uiStyle = uiMode || mode
const isTablet = useMediaQuery('(max-width: 1024px)')
const {
backgroundColor = mode === UiMode.DARK ? '#1E1E1E' : 'white',
backgroundColor = uiStyle === UiMode.DARK ? '#1E1E1E' : 'white',
width = '100%',
maxWidth = isTablet ? '448px' : '649px',
height = 'max-content',
Expand Down
22 changes: 11 additions & 11 deletions src/views/Onboard/views/ConfigureConnection.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
import Typography from '../../../components/Typography/Typography'
import ConfigConnectionForm from '../../../forms/ConfigConnectionForm'
import TabOption from '../../../components/TabOption/TabOption'
import { ConfigType, UiMode } from '../../../constants/enums'
import ProtocolInput from '../../../components/ProtocolInput/ProtocolInput'
import Input from '../../../components/Input/Input'
import { Controller } from 'react-hook-form'
import Toggle from '../../../components/Toggle/Toggle'
import Button, { ButtonFace } from '../../../components/Button/Button'
import { ReactComponent as LightHouseSVG } from '../../../assets/images/lightHouseLarge.svg'
// import { ReactComponent as LightHouseSVG } from '../../../assets/images/lightHouseLarge.svg'
import { useTranslation } from 'react-i18next'
import Button, { ButtonFace } from '../../../components/Button/Button'
import DeviceSelect from '../../../components/DeviceSelect/DeviceSelect'
import Input from '../../../components/Input/Input'
import ProtocolInput from '../../../components/ProtocolInput/ProtocolInput'
import TabOption from '../../../components/TabOption/TabOption'
import Toggle from '../../../components/Toggle/Toggle'
import Tooltip from '../../../components/ToolTip/Tooltip'
import Typography from '../../../components/Typography/Typography'
import { REQUIRED_VALIDATOR_VERSION } from '../../../constants/constants'
import DeviceSelect from '../../../components/DeviceSelect/DeviceSelect'
import { ConfigType, UiMode } from '../../../constants/enums'
import ConfigConnectionForm from '../../../forms/ConfigConnectionForm'

const ConfigureConnection = () => {
const { t } = useTranslation()
const { major, minor, patch } = REQUIRED_VALIDATOR_VERSION
return (
<div className='flex-1 relative w-full flex flex-col relative justify-center bg-black'>
<LightHouseSVG className='hidden lg:block absolute w-3/4 @1024:w-9/10 xl:w-full -right-45 @1440:-right-35 top-0 animate-spin-slow' />
{/* <LightHouseSVG className='hidden lg:block absolute w-3/4 @1024:w-9/10 xl:w-full -right-45 @1440:-right-35 top-0 animate-spin-slow' /> */}
<div className='h-full w-full overflow-scroll scrollbar-hide lg:max-w-xl xl:max-w-2xl @1440:max-w-3xl p-6 pt-16 md:p-12 md:pt-24 lg:pl-18 lg:pr-0 xl:pl-24 @1440:pl-28'>
<Typography
color='text-transparent'
Expand Down

0 comments on commit a8b89d4

Please sign in to comment.