fix: wizard loading order and zeroConf

This commit is contained in:
Taranto 2020-10-20 11:24:36 +01:00 committed by Josh Harvey
parent 0a491e0522
commit 97ffb7bdf1
17 changed files with 259 additions and 109 deletions

View file

@ -10855,7 +10855,8 @@
},
"kind-of": {
"version": "6.0.2",
"resolved": "",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
"integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
"dev": true
}
}
@ -15026,7 +15027,8 @@
},
"kind-of": {
"version": "6.0.2",
"resolved": "",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
"integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
"dev": true
}
}
@ -19209,8 +19211,30 @@
"integrity": "sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA==",
"requires": {
"define-properties": "^1.1.3",
"es-abstract": "^1.18.0-next.0",
"has-symbols": "^1.0.1",
"object-keys": "^1.1.1"
},
"dependencies": {
"es-abstract": {
"version": "1.18.0-next.1",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz",
"integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==",
"requires": {
"es-to-primitive": "^1.2.1",
"function-bind": "^1.1.1",
"has": "^1.0.3",
"has-symbols": "^1.0.1",
"is-callable": "^1.2.2",
"is-negative-zero": "^2.0.0",
"is-regex": "^1.1.1",
"object-inspect": "^1.8.0",
"object-keys": "^1.1.1",
"object.assign": "^4.1.1",
"string.prototype.trimend": "^1.0.1",
"string.prototype.trimstart": "^1.0.1"
}
}
}
}
}
@ -27804,7 +27828,8 @@
},
"kind-of": {
"version": "6.0.2",
"resolved": "",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
"integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
"dev": true
}
}

View file

@ -1,4 +1,3 @@
import { ApolloProvider, useQuery } from '@apollo/react-hooks'
import CssBaseline from '@material-ui/core/CssBaseline'
import {
StylesProvider,
@ -6,15 +5,12 @@ import {
MuiThemeProvider,
makeStyles
} from '@material-ui/core/styles'
import gql from 'graphql-tag'
import { create } from 'jss'
import extendJss from 'jss-plugin-extend'
import React from 'react'
import { BrowserRouter as Router } from 'react-router-dom'
import React, { createContext, useState } from 'react'
import { useLocation, BrowserRouter as Router } from 'react-router-dom'
import Wizard from 'src/pages/Wizard'
import { getWizardStep } from 'src/pages/Wizard/helper'
import client from 'src/utils/apollo'
import ApolloProvider from 'src/utils/apollo'
import Header from './components/layout/Header'
import { tree, Routes } from './routing/routes'
@ -53,43 +49,31 @@ const useStyles = makeStyles({
}
})
const GET_DATA = gql`
query getData {
config
accounts
cryptoCurrencies {
code
display
}
}
`
const AppContext = createContext()
const Main = () => {
const classes = useStyles()
const { data, loading } = useQuery(GET_DATA)
const location = useLocation()
if (loading) {
return <></>
}
const wizardStep = getWizardStep(data?.config, data?.cryptoCurrencies)
const is404 = location.pathname === '/404'
return (
<div className={classes.root}>
<Router>
{wizardStep > 0 && <Wizard wizardStep={wizardStep} />}
<Header tree={tree} />
{!is404 && <Header tree={tree} />}
<main className={classes.wrapper}>
<Routes />
</main>
</Router>
</div>
)
}
const App = () => {
const [wizardTested, setWizardTested] = useState(false)
return (
<ApolloProvider client={client}>
<AppContext.Provider value={{ wizardTested, setWizardTested }}>
<Router>
<ApolloProvider>
<StylesProvider jss={jss}>
<MuiThemeProvider theme={theme}>
<CssBaseline />
@ -97,7 +81,10 @@ const App = () => {
</MuiThemeProvider>
</StylesProvider>
</ApolloProvider>
</Router>
</AppContext.Provider>
)
}
export default App
export { AppContext }

View file

@ -87,6 +87,9 @@ const validationSchema = Yup.object().shape({
const MachineNameComponent = ({ nextStep, classes, setQrCode, setName }) => {
const [register] = useMutation(SAVE_CONFIG, {
onCompleted: ({ createPairingTotem }) => {
if (process.env.NODE_ENV === 'development') {
console.log(`totem: "${createPairingTotem}" `)
}
setQrCode(createPairingTotem)
nextStep()
},

View file

@ -20,7 +20,7 @@ const AuthRegister = () => {
customHandler: (err, res) => {
if (err) return
if (res) {
history.push('/')
history.push('/wizard', { fromAuthRegister: true })
}
}
})

View file

@ -52,7 +52,6 @@ const getOverridesFields = (getData, currency, auxElements) => {
)
const suggestionFilter = (it, cryptoData) => {
console.log(it)
if (!it?.machine) return cryptoData
return R.differenceWith(

View file

@ -33,7 +33,6 @@ const getCashOutStatus = it => {
}
const getCashInStatus = it => {
console.log(it)
if (it.operatorCompleted) return 'Cancelled'
if (it.hasError) return 'Error'
if (it.sendConfirmed) return 'Sent'

View file

@ -66,7 +66,7 @@ const WizardSplash = ({ code, name, onContinue }) => {
<P className={classes.text}>
You are about to enable {name} on your system. This will allow you to
use this cryptocurrency on your machines. To be able to do that, youll
have to setup all the necessary 3rd party services.
have to set up all the necessary 3rd party services.
</P>
<Button className={classes.button} onClick={onContinue}>
Start configuration

View file

@ -1,11 +1,15 @@
import { useQuery } from '@apollo/react-hooks'
import { makeStyles, Dialog, DialogContent } from '@material-ui/core'
import classnames from 'classnames'
import React, { useState } from 'react'
import gql from 'graphql-tag'
import React, { useState, useContext } from 'react'
import { useHistory } from 'react-router-dom'
import { AppContext } from 'src/App'
import { getWizardStep, STEPS } from 'src/pages/Wizard/helper'
import { backgroundColor } from 'src/styling/variables'
import Footer from './components/Footer'
import { STEPS } from './helper'
const useStyles = makeStyles({
wrapper: {
@ -26,12 +30,42 @@ const useStyles = makeStyles({
}
})
const Wizard = ({ wizardStep }) => {
const [step, setStep] = useState(0)
const GET_DATA = gql`
query getData {
config
accounts
cryptoCurrencies {
code
display
}
}
`
const Wizard = ({ fromAuthRegister }) => {
const classes = useStyles()
const { data, loading } = useQuery(GET_DATA)
const history = useHistory()
const { setWizardTested } = useContext(AppContext)
const [step, setStep] = useState(0)
const [open, setOpen] = useState(true)
const [footerExp, setFooterExp] = useState(false)
if (loading) {
return <></>
}
const wizardStep = getWizardStep(data?.config, data?.cryptoCurrencies)
const shouldGoBack =
history.length && !history.location.state?.fromAuthRegister
if (wizardStep === 0) {
setWizardTested(true)
shouldGoBack ? history.goBack() : history.push('/')
}
const isWelcome = step === 0
const classNames = {
[classes.blurred]: footerExp,
@ -44,13 +78,17 @@ const Wizard = ({ wizardStep }) => {
}
const doContinue = () => {
if (step >= STEPS.length - 1) return setOpen(false)
if (step >= STEPS.length - 1) {
setOpen(false)
history.push('/')
}
const nextStep = step === 0 && wizardStep ? wizardStep : step + 1
setFooterExp(true)
setStep(nextStep)
}
const current = STEPS[step]
return (

View file

@ -1,6 +1,7 @@
import { useQuery, useMutation } from '@apollo/react-hooks'
import { makeStyles } from '@material-ui/core'
import gql from 'graphql-tag'
import * as R from 'ramda'
import React from 'react'
import { Table as EditableTable } from 'src/components/editableTable'
@ -14,6 +15,8 @@ import {
} from 'src/pages/Locales/helper'
import { toNamespace } from 'src/utils/config'
import { getConfiguredCoins } from '../helper'
const useStyles = makeStyles(styles)
const GET_DATA = gql`
@ -62,6 +65,11 @@ function Locales({ isActive, doContinue }) {
return saveConfig({ variables: { config } })
}
const cryptoCurrencies = getConfiguredCoins(
data?.config || {},
data?.cryptoCurrencies || []
)
return (
<div className={classes.wrapper}>
<TitleSection title="Locales" />
@ -77,7 +85,7 @@ function Locales({ isActive, doContinue }) {
save={save}
validationSchema={schema}
data={[]}
elements={mainFields(data)}
elements={mainFields(R.merge(data, { cryptoCurrencies }))}
/>
</Section>
</div>

View file

@ -101,7 +101,7 @@ const Mailgun = () => {
<div className={classes.infoMessage}>
<WarningIcon />
<Info3>
To get email notifications, youll need to setup Mailgun. Check out
To get email notifications, youll need to set up Mailgun. Check out
our article on how to set it up.
</Info3>
</div>

View file

@ -39,7 +39,6 @@ const SAVE_CONFIG = gql`
const AllSet = ({ data: currentData, doContinue }) => {
const classes = useStyles()
console.log(currentData)
const { data } = useQuery(GET_INFO)
const [saveConfig] = useMutation(SAVE_CONFIG, {

View file

@ -36,6 +36,11 @@ const ChooseCoin = ({ addData }) => {
const onSubmit = it => {
if (!schema.isValidSync(it)) return setError(true)
if (it.coin !== 'BTC') {
return addData({ coin: it.coin, zeroConf: 'all-zero-conf' })
}
addData(it)
}

View file

@ -95,13 +95,28 @@ const ChooseWallet = ({ data: currentData, addData }) => {
onChange={onSelect}
/>
{isLocalHosted(selected) && (
<>
<div className={classes.infoMessage}>
<WarningIcon />
<Info3>
To setup {selected} please read our instructions from our support
article.
To set up {selected} please read the node wallet instructions from
our support portal.
</Info3>
</div>
<a
className={classes.actionButtonLink}
target="_blank"
rel="noopener noreferrer"
href="https://support.lamassu.is/hc/en-us/articles/115001209552-Setting-up-your-node-wallets">
<ActionButton
className={classes.actionButton}
color="primary"
Icon={LinkIcon}
InverseIcon={InverseLinkIcon}>
Support article
</ActionButton>
</a>
</>
)}
{!isConfigurable(selected) && (
<Button size="lg" onClick={submit} className={classes.button}>

View file

@ -14,6 +14,13 @@ import Twilio from './components/Twilio'
import Wallet from './components/Wallet/Wallet'
import Welcome from './components/Welcome'
const getConfiguredCoins = (config, crypto) => {
const wallet = fromNamespace(namespaces.WALLETS, config)
return R.filter(it =>
WalletSchema.isValidSync(fromNamespace(it.code, wallet))
)(crypto)
}
const hasValidWallet = (config, crypto) => {
const wallet = fromNamespace(namespaces.WALLETS, config)
const coins = R.map(it => fromNamespace(it.code, wallet))(crypto)
@ -61,9 +68,9 @@ const STEPS = [
Component: Wallet,
exImage: '/assets/wizard/fullexample.wallet.png',
subtitle: 'Wallet settings',
text: `Your wallet settings are the first step for this wizard. We'll start
by setting one of cryptocurrency to get you up and running, but you
can later setup as many cryptocurrencies as you want.`
text: `Your wallet settings are the first step for this wizard.
We'll start by setting up one of cryptocurrencies to get you up and running,
but you can later set up as many as you want.`
},
{
id: 'locale',
@ -125,4 +132,4 @@ const STEPS = [
// }
]
export { getWizardStep, STEPS }
export { getWizardStep, STEPS, getConfiguredCoins }

View file

@ -0,0 +1,27 @@
import React from 'react'
import { Route, Redirect } from 'react-router-dom'
const isAuthenticated = () => {
return localStorage.getItem('loggedIn')
}
const PrivateRoute = ({ children, ...rest }) => {
return (
<Route
{...rest}
render={({ location }) =>
isAuthenticated() ? (
children
) : (
<Redirect
to={{
pathname: '/login'
}}
/>
)
}
/>
)
}
export default PrivateRoute

View file

@ -1,7 +1,14 @@
import * as R from 'ramda'
import React from 'react'
import { Route, Redirect, Switch } from 'react-router-dom'
import React, { useContext } from 'react'
import {
Route,
Redirect,
Switch,
useHistory,
useLocation
} from 'react-router-dom'
import { AppContext } from 'src/App'
import AuthRegister from 'src/pages/AuthRegister'
import Cashout from 'src/pages/Cashout'
import Commissions from 'src/pages/Commissions'
@ -154,17 +161,34 @@ const leafRoutes = R.compose(R.flatten, map)(tree)
const parentRoutes = R.filter(R.has('children'))(tree)
const flattened = R.concat(leafRoutes, parentRoutes)
const Routes = () => (
const Routes = () => {
const history = useHistory()
const location = useLocation()
const { wizardTested } = useContext(AppContext)
const dontTriggerPages = ['/404', '/register', '/wizard']
if (!wizardTested && !R.contains(location.pathname)(dontTriggerPages)) {
history.push('/wizard')
}
return (
<Switch>
<Route exact path="/" />
<Route exact path="/">
<Redirect to={{ pathname: '/transactions' }} />
</Route>
<Route path="/wizard" component={Wizard} />
<Route path="/register" component={AuthRegister} />
<Route path="/wizard" component={Wizard}></Route>
{flattened.map(({ route, component: Page, key }) => (
<Route path={route} key={key}>
<Page name={key} />
</Route>
))}
<Route path="/404" />
<Route path="*">
<Redirect to={{ pathname: '/404' }} />
</Route>
</Switch>
)
)
}
export { tree, Routes }

View file

@ -1,21 +1,28 @@
import { ApolloProvider } from '@apollo/react-hooks'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { ApolloClient } from 'apollo-client'
import { ApolloLink } from 'apollo-link'
import { onError } from 'apollo-link-error'
import { HttpLink } from 'apollo-link-http'
import React from 'react'
import { useHistory, useLocation } from 'react-router-dom'
const URI =
process.env.NODE_ENV === 'development' ? 'https://localhost:8070' : ''
const client = new ApolloClient({
const getClient = (history, location) =>
new ApolloClient({
link: ApolloLink.from([
onError(({ graphQLErrors, networkError }) => {
if (graphQLErrors)
graphQLErrors.forEach(({ message, locations, path }) =>
graphQLErrors.forEach(({ message, locations, path, extensions }) => {
if (extensions?.code === 'UNAUTHENTICATED') {
if (location.pathname !== '/404') history.push('/404')
}
console.log(
`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`
)
)
})
if (networkError) console.log(`[Network error]: ${networkError}`)
}),
new HttpLink({
@ -37,7 +44,14 @@ const client = new ApolloClient({
errorPolicy: 'all'
}
}
})
})
export default client
const Provider = ({ children }) => {
const history = useHistory()
const location = useLocation()
const client = getClient(history, location)
return <ApolloProvider client={client}>{children}</ApolloProvider>
}
export default Provider
export { URI }