fix: wizard loading order and zeroConf
This commit is contained in:
parent
0a491e0522
commit
97ffb7bdf1
17 changed files with 259 additions and 109 deletions
31
new-lamassu-admin/package-lock.json
generated
31
new-lamassu-admin/package-lock.json
generated
|
|
@ -10855,7 +10855,8 @@
|
||||||
},
|
},
|
||||||
"kind-of": {
|
"kind-of": {
|
||||||
"version": "6.0.2",
|
"version": "6.0.2",
|
||||||
"resolved": "",
|
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
|
||||||
|
"integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -15026,7 +15027,8 @@
|
||||||
},
|
},
|
||||||
"kind-of": {
|
"kind-of": {
|
||||||
"version": "6.0.2",
|
"version": "6.0.2",
|
||||||
"resolved": "",
|
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
|
||||||
|
"integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -19209,8 +19211,30 @@
|
||||||
"integrity": "sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA==",
|
"integrity": "sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"define-properties": "^1.1.3",
|
"define-properties": "^1.1.3",
|
||||||
|
"es-abstract": "^1.18.0-next.0",
|
||||||
"has-symbols": "^1.0.1",
|
"has-symbols": "^1.0.1",
|
||||||
"object-keys": "^1.1.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": {
|
"kind-of": {
|
||||||
"version": "6.0.2",
|
"version": "6.0.2",
|
||||||
"resolved": "",
|
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
|
||||||
|
"integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import { ApolloProvider, useQuery } from '@apollo/react-hooks'
|
|
||||||
import CssBaseline from '@material-ui/core/CssBaseline'
|
import CssBaseline from '@material-ui/core/CssBaseline'
|
||||||
import {
|
import {
|
||||||
StylesProvider,
|
StylesProvider,
|
||||||
|
|
@ -6,15 +5,12 @@ import {
|
||||||
MuiThemeProvider,
|
MuiThemeProvider,
|
||||||
makeStyles
|
makeStyles
|
||||||
} from '@material-ui/core/styles'
|
} from '@material-ui/core/styles'
|
||||||
import gql from 'graphql-tag'
|
|
||||||
import { create } from 'jss'
|
import { create } from 'jss'
|
||||||
import extendJss from 'jss-plugin-extend'
|
import extendJss from 'jss-plugin-extend'
|
||||||
import React from 'react'
|
import React, { createContext, useState } from 'react'
|
||||||
import { BrowserRouter as Router } from 'react-router-dom'
|
import { useLocation, BrowserRouter as Router } from 'react-router-dom'
|
||||||
|
|
||||||
import Wizard from 'src/pages/Wizard'
|
import ApolloProvider from 'src/utils/apollo'
|
||||||
import { getWizardStep } from 'src/pages/Wizard/helper'
|
|
||||||
import client from 'src/utils/apollo'
|
|
||||||
|
|
||||||
import Header from './components/layout/Header'
|
import Header from './components/layout/Header'
|
||||||
import { tree, Routes } from './routing/routes'
|
import { tree, Routes } from './routing/routes'
|
||||||
|
|
@ -53,51 +49,42 @@ const useStyles = makeStyles({
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const GET_DATA = gql`
|
const AppContext = createContext()
|
||||||
query getData {
|
|
||||||
config
|
|
||||||
accounts
|
|
||||||
cryptoCurrencies {
|
|
||||||
code
|
|
||||||
display
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const Main = () => {
|
const Main = () => {
|
||||||
const classes = useStyles()
|
const classes = useStyles()
|
||||||
const { data, loading } = useQuery(GET_DATA)
|
const location = useLocation()
|
||||||
|
|
||||||
if (loading) {
|
const is404 = location.pathname === '/404'
|
||||||
return <></>
|
|
||||||
}
|
|
||||||
|
|
||||||
const wizardStep = getWizardStep(data?.config, data?.cryptoCurrencies)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classes.root}>
|
<div className={classes.root}>
|
||||||
<Router>
|
{!is404 && <Header tree={tree} />}
|
||||||
{wizardStep > 0 && <Wizard wizardStep={wizardStep} />}
|
<main className={classes.wrapper}>
|
||||||
<Header tree={tree} />
|
<Routes />
|
||||||
<main className={classes.wrapper}>
|
</main>
|
||||||
<Routes />
|
|
||||||
</main>
|
|
||||||
</Router>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
|
const [wizardTested, setWizardTested] = useState(false)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ApolloProvider client={client}>
|
<AppContext.Provider value={{ wizardTested, setWizardTested }}>
|
||||||
<StylesProvider jss={jss}>
|
<Router>
|
||||||
<MuiThemeProvider theme={theme}>
|
<ApolloProvider>
|
||||||
<CssBaseline />
|
<StylesProvider jss={jss}>
|
||||||
<Main />
|
<MuiThemeProvider theme={theme}>
|
||||||
</MuiThemeProvider>
|
<CssBaseline />
|
||||||
</StylesProvider>
|
<Main />
|
||||||
</ApolloProvider>
|
</MuiThemeProvider>
|
||||||
|
</StylesProvider>
|
||||||
|
</ApolloProvider>
|
||||||
|
</Router>
|
||||||
|
</AppContext.Provider>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default App
|
export default App
|
||||||
|
export { AppContext }
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,9 @@ const validationSchema = Yup.object().shape({
|
||||||
const MachineNameComponent = ({ nextStep, classes, setQrCode, setName }) => {
|
const MachineNameComponent = ({ nextStep, classes, setQrCode, setName }) => {
|
||||||
const [register] = useMutation(SAVE_CONFIG, {
|
const [register] = useMutation(SAVE_CONFIG, {
|
||||||
onCompleted: ({ createPairingTotem }) => {
|
onCompleted: ({ createPairingTotem }) => {
|
||||||
|
if (process.env.NODE_ENV === 'development') {
|
||||||
|
console.log(`totem: "${createPairingTotem}" `)
|
||||||
|
}
|
||||||
setQrCode(createPairingTotem)
|
setQrCode(createPairingTotem)
|
||||||
nextStep()
|
nextStep()
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ const AuthRegister = () => {
|
||||||
customHandler: (err, res) => {
|
customHandler: (err, res) => {
|
||||||
if (err) return
|
if (err) return
|
||||||
if (res) {
|
if (res) {
|
||||||
history.push('/')
|
history.push('/wizard', { fromAuthRegister: true })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,6 @@ const getOverridesFields = (getData, currency, auxElements) => {
|
||||||
)
|
)
|
||||||
|
|
||||||
const suggestionFilter = (it, cryptoData) => {
|
const suggestionFilter = (it, cryptoData) => {
|
||||||
console.log(it)
|
|
||||||
if (!it?.machine) return cryptoData
|
if (!it?.machine) return cryptoData
|
||||||
|
|
||||||
return R.differenceWith(
|
return R.differenceWith(
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,6 @@ const getCashOutStatus = it => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const getCashInStatus = it => {
|
const getCashInStatus = it => {
|
||||||
console.log(it)
|
|
||||||
if (it.operatorCompleted) return 'Cancelled'
|
if (it.operatorCompleted) return 'Cancelled'
|
||||||
if (it.hasError) return 'Error'
|
if (it.hasError) return 'Error'
|
||||||
if (it.sendConfirmed) return 'Sent'
|
if (it.sendConfirmed) return 'Sent'
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ const WizardSplash = ({ code, name, onContinue }) => {
|
||||||
<P className={classes.text}>
|
<P className={classes.text}>
|
||||||
You are about to enable {name} on your system. This will allow you to
|
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, you’ll
|
use this cryptocurrency on your machines. To be able to do that, you’ll
|
||||||
have to setup all the necessary 3rd party services.
|
have to set up all the necessary 3rd party services.
|
||||||
</P>
|
</P>
|
||||||
<Button className={classes.button} onClick={onContinue}>
|
<Button className={classes.button} onClick={onContinue}>
|
||||||
Start configuration
|
Start configuration
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,15 @@
|
||||||
|
import { useQuery } from '@apollo/react-hooks'
|
||||||
import { makeStyles, Dialog, DialogContent } from '@material-ui/core'
|
import { makeStyles, Dialog, DialogContent } from '@material-ui/core'
|
||||||
import classnames from 'classnames'
|
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 { backgroundColor } from 'src/styling/variables'
|
||||||
|
|
||||||
import Footer from './components/Footer'
|
import Footer from './components/Footer'
|
||||||
import { STEPS } from './helper'
|
|
||||||
|
|
||||||
const useStyles = makeStyles({
|
const useStyles = makeStyles({
|
||||||
wrapper: {
|
wrapper: {
|
||||||
|
|
@ -26,12 +30,42 @@ const useStyles = makeStyles({
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const Wizard = ({ wizardStep }) => {
|
const GET_DATA = gql`
|
||||||
const [step, setStep] = useState(0)
|
query getData {
|
||||||
|
config
|
||||||
|
accounts
|
||||||
|
cryptoCurrencies {
|
||||||
|
code
|
||||||
|
display
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const Wizard = ({ fromAuthRegister }) => {
|
||||||
const classes = useStyles()
|
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 [open, setOpen] = useState(true)
|
||||||
|
|
||||||
const [footerExp, setFooterExp] = useState(false)
|
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 isWelcome = step === 0
|
||||||
const classNames = {
|
const classNames = {
|
||||||
[classes.blurred]: footerExp,
|
[classes.blurred]: footerExp,
|
||||||
|
|
@ -44,13 +78,17 @@ const Wizard = ({ wizardStep }) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const doContinue = () => {
|
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
|
const nextStep = step === 0 && wizardStep ? wizardStep : step + 1
|
||||||
|
|
||||||
setFooterExp(true)
|
setFooterExp(true)
|
||||||
setStep(nextStep)
|
setStep(nextStep)
|
||||||
}
|
}
|
||||||
|
|
||||||
const current = STEPS[step]
|
const current = STEPS[step]
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { useQuery, useMutation } from '@apollo/react-hooks'
|
import { useQuery, useMutation } from '@apollo/react-hooks'
|
||||||
import { makeStyles } from '@material-ui/core'
|
import { makeStyles } from '@material-ui/core'
|
||||||
import gql from 'graphql-tag'
|
import gql from 'graphql-tag'
|
||||||
|
import * as R from 'ramda'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
|
||||||
import { Table as EditableTable } from 'src/components/editableTable'
|
import { Table as EditableTable } from 'src/components/editableTable'
|
||||||
|
|
@ -14,6 +15,8 @@ import {
|
||||||
} from 'src/pages/Locales/helper'
|
} from 'src/pages/Locales/helper'
|
||||||
import { toNamespace } from 'src/utils/config'
|
import { toNamespace } from 'src/utils/config'
|
||||||
|
|
||||||
|
import { getConfiguredCoins } from '../helper'
|
||||||
|
|
||||||
const useStyles = makeStyles(styles)
|
const useStyles = makeStyles(styles)
|
||||||
|
|
||||||
const GET_DATA = gql`
|
const GET_DATA = gql`
|
||||||
|
|
@ -62,6 +65,11 @@ function Locales({ isActive, doContinue }) {
|
||||||
return saveConfig({ variables: { config } })
|
return saveConfig({ variables: { config } })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const cryptoCurrencies = getConfiguredCoins(
|
||||||
|
data?.config || {},
|
||||||
|
data?.cryptoCurrencies || []
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classes.wrapper}>
|
<div className={classes.wrapper}>
|
||||||
<TitleSection title="Locales" />
|
<TitleSection title="Locales" />
|
||||||
|
|
@ -77,7 +85,7 @@ function Locales({ isActive, doContinue }) {
|
||||||
save={save}
|
save={save}
|
||||||
validationSchema={schema}
|
validationSchema={schema}
|
||||||
data={[]}
|
data={[]}
|
||||||
elements={mainFields(data)}
|
elements={mainFields(R.merge(data, { cryptoCurrencies }))}
|
||||||
/>
|
/>
|
||||||
</Section>
|
</Section>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ const Mailgun = () => {
|
||||||
<div className={classes.infoMessage}>
|
<div className={classes.infoMessage}>
|
||||||
<WarningIcon />
|
<WarningIcon />
|
||||||
<Info3>
|
<Info3>
|
||||||
To get email notifications, you’ll need to setup Mailgun. Check out
|
To get email notifications, you’ll need to set up Mailgun. Check out
|
||||||
our article on how to set it up.
|
our article on how to set it up.
|
||||||
</Info3>
|
</Info3>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,6 @@ const SAVE_CONFIG = gql`
|
||||||
|
|
||||||
const AllSet = ({ data: currentData, doContinue }) => {
|
const AllSet = ({ data: currentData, doContinue }) => {
|
||||||
const classes = useStyles()
|
const classes = useStyles()
|
||||||
console.log(currentData)
|
|
||||||
|
|
||||||
const { data } = useQuery(GET_INFO)
|
const { data } = useQuery(GET_INFO)
|
||||||
const [saveConfig] = useMutation(SAVE_CONFIG, {
|
const [saveConfig] = useMutation(SAVE_CONFIG, {
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,11 @@ const ChooseCoin = ({ addData }) => {
|
||||||
|
|
||||||
const onSubmit = it => {
|
const onSubmit = it => {
|
||||||
if (!schema.isValidSync(it)) return setError(true)
|
if (!schema.isValidSync(it)) return setError(true)
|
||||||
|
|
||||||
|
if (it.coin !== 'BTC') {
|
||||||
|
return addData({ coin: it.coin, zeroConf: 'all-zero-conf' })
|
||||||
|
}
|
||||||
|
|
||||||
addData(it)
|
addData(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -95,13 +95,28 @@ const ChooseWallet = ({ data: currentData, addData }) => {
|
||||||
onChange={onSelect}
|
onChange={onSelect}
|
||||||
/>
|
/>
|
||||||
{isLocalHosted(selected) && (
|
{isLocalHosted(selected) && (
|
||||||
<div className={classes.infoMessage}>
|
<>
|
||||||
<WarningIcon />
|
<div className={classes.infoMessage}>
|
||||||
<Info3>
|
<WarningIcon />
|
||||||
To setup {selected} please read our instructions from our support
|
<Info3>
|
||||||
article.
|
To set up {selected} please read the node wallet instructions from
|
||||||
</Info3>
|
our support portal.
|
||||||
</div>
|
</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) && (
|
{!isConfigurable(selected) && (
|
||||||
<Button size="lg" onClick={submit} className={classes.button}>
|
<Button size="lg" onClick={submit} className={classes.button}>
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,13 @@ import Twilio from './components/Twilio'
|
||||||
import Wallet from './components/Wallet/Wallet'
|
import Wallet from './components/Wallet/Wallet'
|
||||||
import Welcome from './components/Welcome'
|
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 hasValidWallet = (config, crypto) => {
|
||||||
const wallet = fromNamespace(namespaces.WALLETS, config)
|
const wallet = fromNamespace(namespaces.WALLETS, config)
|
||||||
const coins = R.map(it => fromNamespace(it.code, wallet))(crypto)
|
const coins = R.map(it => fromNamespace(it.code, wallet))(crypto)
|
||||||
|
|
@ -61,9 +68,9 @@ const STEPS = [
|
||||||
Component: Wallet,
|
Component: Wallet,
|
||||||
exImage: '/assets/wizard/fullexample.wallet.png',
|
exImage: '/assets/wizard/fullexample.wallet.png',
|
||||||
subtitle: 'Wallet settings',
|
subtitle: 'Wallet settings',
|
||||||
text: `Your wallet settings are the first step for this wizard. We'll start
|
text: `Your wallet settings are the first step for this wizard.
|
||||||
by setting one of cryptocurrency to get you up and running, but you
|
We'll start by setting up one of cryptocurrencies to get you up and running,
|
||||||
can later setup as many cryptocurrencies as you want.`
|
but you can later set up as many as you want.`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'locale',
|
id: 'locale',
|
||||||
|
|
@ -125,4 +132,4 @@ const STEPS = [
|
||||||
// }
|
// }
|
||||||
]
|
]
|
||||||
|
|
||||||
export { getWizardStep, STEPS }
|
export { getWizardStep, STEPS, getConfiguredCoins }
|
||||||
|
|
|
||||||
27
new-lamassu-admin/src/routing/PrivateRoute.js
Normal file
27
new-lamassu-admin/src/routing/PrivateRoute.js
Normal 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
|
||||||
|
|
@ -1,7 +1,14 @@
|
||||||
import * as R from 'ramda'
|
import * as R from 'ramda'
|
||||||
import React from 'react'
|
import React, { useContext } from 'react'
|
||||||
import { Route, Redirect, Switch } from 'react-router-dom'
|
import {
|
||||||
|
Route,
|
||||||
|
Redirect,
|
||||||
|
Switch,
|
||||||
|
useHistory,
|
||||||
|
useLocation
|
||||||
|
} from 'react-router-dom'
|
||||||
|
|
||||||
|
import { AppContext } from 'src/App'
|
||||||
import AuthRegister from 'src/pages/AuthRegister'
|
import AuthRegister from 'src/pages/AuthRegister'
|
||||||
import Cashout from 'src/pages/Cashout'
|
import Cashout from 'src/pages/Cashout'
|
||||||
import Commissions from 'src/pages/Commissions'
|
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 parentRoutes = R.filter(R.has('children'))(tree)
|
||||||
const flattened = R.concat(leafRoutes, parentRoutes)
|
const flattened = R.concat(leafRoutes, parentRoutes)
|
||||||
|
|
||||||
const Routes = () => (
|
const Routes = () => {
|
||||||
<Switch>
|
const history = useHistory()
|
||||||
<Route exact path="/" />
|
const location = useLocation()
|
||||||
<Route path="/register" component={AuthRegister} />
|
const { wizardTested } = useContext(AppContext)
|
||||||
<Route path="/wizard" component={Wizard}></Route>
|
|
||||||
{flattened.map(({ route, component: Page, key }) => (
|
|
||||||
<Route path={route} key={key}>
|
|
||||||
<Page name={key} />
|
|
||||||
</Route>
|
|
||||||
))}
|
|
||||||
</Switch>
|
|
||||||
)
|
|
||||||
|
|
||||||
|
const dontTriggerPages = ['/404', '/register', '/wizard']
|
||||||
|
|
||||||
|
if (!wizardTested && !R.contains(location.pathname)(dontTriggerPages)) {
|
||||||
|
history.push('/wizard')
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Switch>
|
||||||
|
<Route exact path="/">
|
||||||
|
<Redirect to={{ pathname: '/transactions' }} />
|
||||||
|
</Route>
|
||||||
|
<Route path="/wizard" component={Wizard} />
|
||||||
|
<Route path="/register" component={AuthRegister} />
|
||||||
|
{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 }
|
export { tree, Routes }
|
||||||
|
|
|
||||||
|
|
@ -1,43 +1,57 @@
|
||||||
|
import { ApolloProvider } from '@apollo/react-hooks'
|
||||||
import { InMemoryCache } from 'apollo-cache-inmemory'
|
import { InMemoryCache } from 'apollo-cache-inmemory'
|
||||||
import { ApolloClient } from 'apollo-client'
|
import { ApolloClient } from 'apollo-client'
|
||||||
import { ApolloLink } from 'apollo-link'
|
import { ApolloLink } from 'apollo-link'
|
||||||
import { onError } from 'apollo-link-error'
|
import { onError } from 'apollo-link-error'
|
||||||
import { HttpLink } from 'apollo-link-http'
|
import { HttpLink } from 'apollo-link-http'
|
||||||
|
import React from 'react'
|
||||||
|
import { useHistory, useLocation } from 'react-router-dom'
|
||||||
|
|
||||||
const URI =
|
const URI =
|
||||||
process.env.NODE_ENV === 'development' ? 'https://localhost:8070' : ''
|
process.env.NODE_ENV === 'development' ? 'https://localhost:8070' : ''
|
||||||
|
|
||||||
const client = new ApolloClient({
|
const getClient = (history, location) =>
|
||||||
link: ApolloLink.from([
|
new ApolloClient({
|
||||||
onError(({ graphQLErrors, networkError }) => {
|
link: ApolloLink.from([
|
||||||
if (graphQLErrors)
|
onError(({ graphQLErrors, networkError }) => {
|
||||||
graphQLErrors.forEach(({ message, locations, path }) =>
|
if (graphQLErrors)
|
||||||
console.log(
|
graphQLErrors.forEach(({ message, locations, path, extensions }) => {
|
||||||
`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`
|
if (extensions?.code === 'UNAUTHENTICATED') {
|
||||||
)
|
if (location.pathname !== '/404') history.push('/404')
|
||||||
)
|
}
|
||||||
if (networkError) console.log(`[Network error]: ${networkError}`)
|
console.log(
|
||||||
}),
|
`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`
|
||||||
new HttpLink({
|
)
|
||||||
credentials: 'include',
|
})
|
||||||
uri: `${URI}/graphql`
|
if (networkError) console.log(`[Network error]: ${networkError}`)
|
||||||
})
|
}),
|
||||||
]),
|
new HttpLink({
|
||||||
cache: new InMemoryCache(),
|
credentials: 'include',
|
||||||
defaultOptions: {
|
uri: `${URI}/graphql`
|
||||||
watchQuery: {
|
})
|
||||||
fetchPolicy: 'no-cache',
|
]),
|
||||||
errorPolicy: 'ignore'
|
cache: new InMemoryCache(),
|
||||||
},
|
defaultOptions: {
|
||||||
query: {
|
watchQuery: {
|
||||||
fetchPolicy: 'no-cache',
|
fetchPolicy: 'no-cache',
|
||||||
errorPolicy: 'all'
|
errorPolicy: 'ignore'
|
||||||
},
|
},
|
||||||
mutate: {
|
query: {
|
||||||
errorPolicy: 'all'
|
fetchPolicy: 'no-cache',
|
||||||
|
errorPolicy: 'all'
|
||||||
|
},
|
||||||
|
mutate: {
|
||||||
|
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 }
|
export { URI }
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue