chore: use monorepo organization
This commit is contained in:
parent
deaf7d6ecc
commit
a687827f7e
1099 changed files with 8184 additions and 11535 deletions
|
|
@ -0,0 +1,62 @@
|
|||
import { useQuery, useMutation, gql } from '@apollo/client'
|
||||
import * as R from 'ramda'
|
||||
import React from 'react'
|
||||
import Section from 'src/components/layout/Section'
|
||||
import TitleSection from 'src/components/layout/TitleSection'
|
||||
import { mainFields, defaults, getSchema } from 'src/pages/Commissions/helper'
|
||||
|
||||
import { Table as EditableTable } from 'src/components/editableTable'
|
||||
import { fromNamespace, toNamespace, namespaces } from 'src/utils/config'
|
||||
|
||||
const GET_DATA = gql`
|
||||
query getData {
|
||||
config
|
||||
}
|
||||
`
|
||||
const SAVE_CONFIG = gql`
|
||||
mutation Save($config: JSONObject) {
|
||||
saveConfig(config: $config)
|
||||
}
|
||||
`
|
||||
|
||||
function Commissions({ isActive, doContinue }) {
|
||||
const { data } = useQuery(GET_DATA)
|
||||
|
||||
const [saveConfig] = useMutation(SAVE_CONFIG, {
|
||||
onCompleted: doContinue
|
||||
})
|
||||
|
||||
const save = it => {
|
||||
const config = toNamespace('commissions')(it.commissions[0])
|
||||
return saveConfig({ variables: { config } })
|
||||
}
|
||||
|
||||
const currency = R.path(['fiatCurrency'])(
|
||||
fromNamespace(namespaces.LOCALE)(data?.config)
|
||||
)
|
||||
|
||||
const locale = fromNamespace(namespaces.LOCALE)(data?.config)
|
||||
|
||||
return (
|
||||
<div className="w-[1132px] h-full mx-auto flex-1 flex flex-col">
|
||||
<TitleSection title="Commissions" />
|
||||
<Section>
|
||||
<EditableTable
|
||||
title="Default setup"
|
||||
rowSize="lg"
|
||||
titleLg
|
||||
name="commissions"
|
||||
initialValues={defaults}
|
||||
enableEdit
|
||||
forceAdd={isActive}
|
||||
save={save}
|
||||
validationSchema={getSchema(locale)}
|
||||
data={[]}
|
||||
elements={mainFields(currency)}
|
||||
/>
|
||||
</Section>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Commissions
|
||||
104
packages/admin-ui/src/pages/Wizard/components/Footer.jsx
Normal file
104
packages/admin-ui/src/pages/Wizard/components/Footer.jsx
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
import Drawer from '@mui/material/Drawer'
|
||||
import Grid from '@mui/material/Grid'
|
||||
import React, { useState } from 'react'
|
||||
import Modal from 'src/components/Modal'
|
||||
import Stepper from 'src/components/Stepper'
|
||||
import { P, H2, Info2 } from 'src/components/typography'
|
||||
|
||||
import { Button, Link } from 'src/components/buttons'
|
||||
|
||||
function Footer({ currentStep, steps, subtitle, text, exImage, open, start }) {
|
||||
const [fullExample, setFullExample] = useState(false)
|
||||
|
||||
return (
|
||||
<Drawer
|
||||
anchor={'bottom'}
|
||||
open={true}
|
||||
variant={'persistent'}
|
||||
classes={{ paperAnchorDockedBottom: 'border-t-0 shadow-sm' }}>
|
||||
<div className={`py-8 flex-grow ${open ? 'h-[264px]' : 'h-[84px]'}`}>
|
||||
<Grid
|
||||
container
|
||||
direction="row"
|
||||
justifyContent="center"
|
||||
alignItems="baseline">
|
||||
<Grid
|
||||
item
|
||||
xs={5}
|
||||
container
|
||||
direction={open ? 'column' : 'row'}
|
||||
justifyContent="flex-start"
|
||||
alignItems="baseline">
|
||||
<H2 className="m-0 mr-8">Setup Lamassu Admin</H2>
|
||||
<Info2 className="mt-2 mb-2 leading-tight inline">{subtitle}</Info2>
|
||||
{open && <P>{text}</P>}
|
||||
</Grid>
|
||||
<Grid
|
||||
item
|
||||
xs={4}
|
||||
container
|
||||
direction="column"
|
||||
justifyContent="flex-start"
|
||||
alignItems="flex-end"
|
||||
spacing={5}>
|
||||
<Grid item xs={12}>
|
||||
{steps && currentStep && (
|
||||
<Stepper currentStep={currentStep} steps={steps} />
|
||||
)}
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
{open && (
|
||||
<Grid
|
||||
container
|
||||
direction="row"
|
||||
justifyContent="center"
|
||||
alignItems="baseline">
|
||||
<Grid
|
||||
item
|
||||
xs={5}
|
||||
container
|
||||
direction="column"
|
||||
justifyContent="flex-start"
|
||||
alignItems="flex-start">
|
||||
<Link
|
||||
onClick={() => {
|
||||
setFullExample(true)
|
||||
}}>
|
||||
See full example
|
||||
</Link>
|
||||
</Grid>
|
||||
<Grid
|
||||
item
|
||||
xs={4}
|
||||
container
|
||||
direction="column"
|
||||
justifyContent="flex-start"
|
||||
alignItems="flex-end"
|
||||
spacing={5}>
|
||||
<Grid item>
|
||||
<Button size="lg" onClick={start}>
|
||||
Get Started
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
)}
|
||||
</div>
|
||||
<Modal
|
||||
closeOnEscape={true}
|
||||
closeOnBackdropClick={true}
|
||||
className="bg-transparent shadow-none"
|
||||
xl={true}
|
||||
width={1152 + 120 + 56}
|
||||
handleClose={() => {
|
||||
setFullExample(false)
|
||||
}}
|
||||
open={fullExample}>
|
||||
<img width={1152} src={exImage} alt="" />
|
||||
</Modal>
|
||||
</Drawer>
|
||||
)
|
||||
}
|
||||
|
||||
export default Footer
|
||||
94
packages/admin-ui/src/pages/Wizard/components/Locales.jsx
Normal file
94
packages/admin-ui/src/pages/Wizard/components/Locales.jsx
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
import { useQuery, useMutation, gql } from '@apollo/client'
|
||||
import * as R from 'ramda'
|
||||
import React from 'react'
|
||||
import Section from 'src/components/layout/Section'
|
||||
import TitleSection from 'src/components/layout/TitleSection'
|
||||
|
||||
import { Table as EditableTable } from 'src/components/editableTable'
|
||||
import {
|
||||
mainFields,
|
||||
localeDefaults as defaults,
|
||||
LocaleSchema as schema
|
||||
} from 'src/pages/Locales/helper'
|
||||
import { toNamespace } from 'src/utils/config'
|
||||
|
||||
import { getConfiguredCoins } from '../helper'
|
||||
|
||||
const GET_DATA = gql`
|
||||
query getData {
|
||||
config
|
||||
accounts
|
||||
currencies {
|
||||
code
|
||||
display
|
||||
}
|
||||
countries {
|
||||
code
|
||||
display
|
||||
}
|
||||
cryptoCurrencies {
|
||||
code
|
||||
display
|
||||
}
|
||||
languages {
|
||||
code
|
||||
display
|
||||
}
|
||||
machines {
|
||||
name
|
||||
deviceId
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const SAVE_CONFIG = gql`
|
||||
mutation Save($config: JSONObject) {
|
||||
saveConfig(config: $config)
|
||||
}
|
||||
`
|
||||
|
||||
function Locales({ isActive, doContinue }) {
|
||||
const { data } = useQuery(GET_DATA)
|
||||
|
||||
const [saveConfig] = useMutation(SAVE_CONFIG, {
|
||||
onCompleted: doContinue
|
||||
})
|
||||
|
||||
const save = it => {
|
||||
const config = toNamespace('locale')(it.locale[0])
|
||||
return saveConfig({ variables: { config } })
|
||||
}
|
||||
|
||||
const cryptoCurrencies = getConfiguredCoins(
|
||||
data?.config || {},
|
||||
data?.cryptoCurrencies || []
|
||||
)
|
||||
|
||||
const onChangeCoin = (prev, curr, setValue) => setValue(curr)
|
||||
|
||||
return (
|
||||
<div className="w-[1132px] h-full mx-auto flex-1 flex flex-col">
|
||||
<TitleSection title="Locales" />
|
||||
<Section>
|
||||
<EditableTable
|
||||
title="Default settings"
|
||||
rowSize="lg"
|
||||
titleLg
|
||||
name="locale"
|
||||
initialValues={defaults}
|
||||
forceAdd={isActive}
|
||||
enableEdit
|
||||
save={save}
|
||||
validationSchema={schema}
|
||||
data={[]}
|
||||
elements={mainFields(
|
||||
R.mergeRight(data, { cryptoCurrencies }),
|
||||
onChangeCoin
|
||||
)}
|
||||
/>
|
||||
</Section>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Locales
|
||||
123
packages/admin-ui/src/pages/Wizard/components/Mailgun.jsx
Normal file
123
packages/admin-ui/src/pages/Wizard/components/Mailgun.jsx
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
import { useMutation, useQuery, gql } from "@apollo/client";
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import { H4, Info3 } from 'src/components/typography'
|
||||
import FormRenderer from 'src/pages/Services/FormRenderer'
|
||||
import InverseLinkIcon from 'src/styling/icons/action/external link/white.svg?react'
|
||||
import LinkIcon from 'src/styling/icons/action/external link/zodiac.svg?react'
|
||||
import WarningIcon from 'src/styling/icons/warning-icon/comet.svg?react'
|
||||
|
||||
import { ActionButton } from 'src/components/buttons'
|
||||
import { RadioGroup } from 'src/components/inputs'
|
||||
import mailgunSchema from 'src/pages/Services/schemas/mailgun'
|
||||
import classes from 'src/pages/Wizard/Radio.module.css'
|
||||
import { fromNamespace, toNamespace, namespaces } from 'src/utils/config'
|
||||
|
||||
const GET_CONFIG = gql`
|
||||
{
|
||||
config
|
||||
accounts
|
||||
}
|
||||
`
|
||||
|
||||
const SAVE_CONFIG = gql`
|
||||
mutation Save($config: JSONObject) {
|
||||
saveConfig(config: $config)
|
||||
}
|
||||
`
|
||||
const SAVE_ACCOUNTS = gql`
|
||||
mutation Save($accounts: JSONObject) {
|
||||
saveAccounts(accounts: $accounts)
|
||||
}
|
||||
`
|
||||
|
||||
const options = [
|
||||
{
|
||||
code: 'enabled',
|
||||
display: 'Yes, send notifications to my email'
|
||||
},
|
||||
{
|
||||
code: 'disabled',
|
||||
display: "No, don't send email notifications"
|
||||
}
|
||||
]
|
||||
|
||||
const Mailgun = () => {
|
||||
const { data } = useQuery(GET_CONFIG)
|
||||
const [saveConfig] = useMutation(SAVE_CONFIG)
|
||||
const [saveAccounts] = useMutation(SAVE_ACCOUNTS)
|
||||
const [emailActive, setEmailActive] = useState(false)
|
||||
const accounts = data?.accounts ?? []
|
||||
|
||||
const emailConfig =
|
||||
data?.config &&
|
||||
fromNamespace(namespaces.NOTIFICATIONS + '_email')(data.config)
|
||||
|
||||
useEffect(() => {
|
||||
if (emailActive) return
|
||||
emailConfig && setEmailActive(emailConfig?.active ? 'enabled' : 'disabled')
|
||||
}, [emailActive, emailConfig])
|
||||
|
||||
const handleRadio = enabled => {
|
||||
setEmailActive(enabled)
|
||||
save(enabled === 'enabled')
|
||||
}
|
||||
|
||||
const save = active => {
|
||||
const config = toNamespace(`notifications_email`)({ active })
|
||||
return saveConfig({ variables: { config } })
|
||||
}
|
||||
|
||||
const saveAccount = mailgun => {
|
||||
const accounts = { mailgun }
|
||||
return saveAccounts({ variables: { accounts } })
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classes.mdForm}>
|
||||
<H4>Do you want to get notifications via email?</H4>
|
||||
<RadioGroup
|
||||
labelClassName={classes.mailgunRadioLabel}
|
||||
className={classes.mailgunRadioGroup}
|
||||
options={options}
|
||||
value={emailActive}
|
||||
onChange={event => handleRadio(event.target.value)}
|
||||
/>
|
||||
|
||||
<div className={classes.infoMessage}>
|
||||
<WarningIcon />
|
||||
<Info3>
|
||||
To get email notifications, you’ll need to set up Mailgun. Check out
|
||||
our article on how to set it up.
|
||||
</Info3>
|
||||
</div>
|
||||
<ActionButton
|
||||
className={classes.actionButton}
|
||||
color="primary"
|
||||
Icon={LinkIcon}
|
||||
InverseIcon={InverseLinkIcon}>
|
||||
<a
|
||||
className={classes.actionButtonLink}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
href="https://support.lamassu.is/hc/en-us/articles/115001203991-Email-notifications-with-Mailgun">
|
||||
Email notifications with Mailgun
|
||||
</a>
|
||||
</ActionButton>
|
||||
|
||||
{emailActive === 'enabled' && (
|
||||
<>
|
||||
<H4>Mailgun credentials</H4>
|
||||
<FormRenderer
|
||||
value={accounts.mailgun}
|
||||
save={saveAccount}
|
||||
elements={mailgunSchema.elements}
|
||||
validationSchema={mailgunSchema.getValidationSchema(accounts.mailgun)}
|
||||
buttonLabel={'Save'}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Mailgun
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
import Grid from '@mui/material/Grid'
|
||||
import React, { useState } from 'react'
|
||||
import Sidebar from 'src/components/layout/Sidebar'
|
||||
import TitleSection from 'src/components/layout/TitleSection'
|
||||
import Notifications from 'src/pages/Notifications/Notifications'
|
||||
|
||||
import { namespaces } from 'src/utils/config'
|
||||
|
||||
import Mailgun from './Mailgun'
|
||||
|
||||
const EMAIL = 'Email'
|
||||
const SETUP_CHANNELS = 'Setup channels'
|
||||
const TRANSACTION_ALERTS = 'Transaction alerts'
|
||||
const FIAT_BALANCE_ALERTS = 'Fiat balance alerts'
|
||||
const CRYPTO_BALANCE_ALERTS = 'Crypto balance alerts'
|
||||
|
||||
const pages = [
|
||||
EMAIL,
|
||||
SETUP_CHANNELS,
|
||||
TRANSACTION_ALERTS,
|
||||
FIAT_BALANCE_ALERTS,
|
||||
CRYPTO_BALANCE_ALERTS
|
||||
]
|
||||
|
||||
const N = () => {
|
||||
const [selected, setSelected] = useState(EMAIL)
|
||||
|
||||
const isSelected = it => selected === it
|
||||
|
||||
return (
|
||||
<div className="w-[1132px] h-full mx-auto flex-1 flex flex-col">
|
||||
<TitleSection title="Notifications"></TitleSection>
|
||||
<Grid container className="flex-1 h-full">
|
||||
<Sidebar
|
||||
data={pages}
|
||||
isSelected={isSelected}
|
||||
displayName={it => it}
|
||||
onClick={it => setSelected(it)}
|
||||
/>
|
||||
<div className="ml-12 pt-4">
|
||||
{isSelected(EMAIL) && <Mailgun />}
|
||||
{isSelected(SETUP_CHANNELS) && (
|
||||
<Notifications
|
||||
name={namespaces.NOTIFICATIONS}
|
||||
wizard={true}
|
||||
displayCryptoAlerts={false}
|
||||
displayOverrides={false}
|
||||
displayTitle={false}
|
||||
displayTransactionAlerts={false}
|
||||
displayFiatAlerts={false}
|
||||
/>
|
||||
)}
|
||||
{isSelected(TRANSACTION_ALERTS) && (
|
||||
<Notifications
|
||||
name={namespaces.NOTIFICATIONS}
|
||||
displayCryptoAlerts={false}
|
||||
displayOverrides={false}
|
||||
displayTitle={false}
|
||||
displaySetup={false}
|
||||
displayFiatAlerts={false}
|
||||
/>
|
||||
)}
|
||||
{isSelected(FIAT_BALANCE_ALERTS) && (
|
||||
<Notifications
|
||||
name={namespaces.NOTIFICATIONS}
|
||||
displayCryptoAlerts={false}
|
||||
displayOverrides={false}
|
||||
displayTitle={false}
|
||||
displayTransactionAlerts={false}
|
||||
displaySetup={false}
|
||||
/>
|
||||
)}
|
||||
{isSelected(CRYPTO_BALANCE_ALERTS) && (
|
||||
<Notifications
|
||||
name={namespaces.NOTIFICATIONS}
|
||||
displaySetup={false}
|
||||
displayOverrides={false}
|
||||
displayTitle={false}
|
||||
displayTransactionAlerts={false}
|
||||
displayFiatAlerts={false}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</Grid>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default N
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
import React from 'react'
|
||||
// import OperatorInfo from 'src/pages/OperatorInfo'
|
||||
|
||||
function WizardOperatorInfo() {
|
||||
return (
|
||||
<div className="w-[1132px] h-full mx-auto flex-1 flex flex-col">
|
||||
{/* <OperatorInfo wizard={true}></OperatorInfo> */}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default WizardOperatorInfo
|
||||
138
packages/admin-ui/src/pages/Wizard/components/Twilio.jsx
Normal file
138
packages/admin-ui/src/pages/Wizard/components/Twilio.jsx
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
import { useMutation, useQuery, gql } from '@apollo/client'
|
||||
import classnames from 'classnames'
|
||||
import React, { useState } from 'react'
|
||||
import { HelpTooltip } from 'src/components/Tooltip'
|
||||
import { H1, H4, Label1, P } from 'src/components/typography'
|
||||
import FormRenderer from 'src/pages/Services/FormRenderer'
|
||||
import WarningIcon from 'src/styling/icons/warning-icon/comet.svg?react'
|
||||
|
||||
import { Button, SupportLinkButton } from 'src/components/buttons'
|
||||
import { RadioGroup } from 'src/components/inputs'
|
||||
import twilio from 'src/pages/Services/schemas/twilio'
|
||||
|
||||
import sharedClasses from './Wallet/Shared.module.css'
|
||||
import classes from './Twilio.module.css'
|
||||
|
||||
const GET_CONFIG = gql`
|
||||
{
|
||||
config
|
||||
accounts
|
||||
}
|
||||
`
|
||||
|
||||
const SAVE_ACCOUNTS = gql`
|
||||
mutation Save($accounts: JSONObject) {
|
||||
saveAccounts(accounts: $accounts)
|
||||
}
|
||||
`
|
||||
|
||||
const options = [
|
||||
{
|
||||
code: 'enable',
|
||||
display: 'Yes, I will'
|
||||
},
|
||||
{
|
||||
code: 'disable',
|
||||
display: 'No, not for now'
|
||||
}
|
||||
]
|
||||
|
||||
function Twilio({ doContinue }) {
|
||||
const [selected, setSelected] = useState(null)
|
||||
const [error, setError] = useState(false)
|
||||
|
||||
const { data, refetch } = useQuery(GET_CONFIG)
|
||||
const [saveAccounts] = useMutation(SAVE_ACCOUNTS, {
|
||||
onCompleted: doContinue
|
||||
})
|
||||
|
||||
const accounts = data?.accounts ?? []
|
||||
|
||||
const onSelect = e => {
|
||||
setSelected(e.target.value)
|
||||
setError(false)
|
||||
}
|
||||
|
||||
const clickContinue = () => {
|
||||
if (!selected) return setError(true)
|
||||
doContinue()
|
||||
}
|
||||
|
||||
const save = twilio => {
|
||||
const accounts = { twilio }
|
||||
return saveAccounts({ variables: { accounts } }).then(() => refetch())
|
||||
}
|
||||
|
||||
const titleClasses = {
|
||||
'ml-2 mb-2': true,
|
||||
[sharedClasses.error]: error
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classes.wrapper}>
|
||||
<div className={classes.content}>
|
||||
<H1>Twilio (SMS service)</H1>
|
||||
<div className="flex items-end">
|
||||
<H4 noMargin className={classnames(titleClasses)}>
|
||||
Will you setup a two way machine or compliance?
|
||||
</H4>
|
||||
<HelpTooltip width={304}>
|
||||
<P>
|
||||
Two-way machines allow your customers not only to buy (cash-in)
|
||||
but also sell cryptocurrencies (cash-out).
|
||||
</P>
|
||||
<P>
|
||||
You’ll need an SMS service for cash-out transactions and for any
|
||||
compliance triggers
|
||||
</P>
|
||||
</HelpTooltip>
|
||||
</div>
|
||||
|
||||
<RadioGroup
|
||||
labelClassName={classes.radioLabel}
|
||||
className={sharedClasses.radioGroup}
|
||||
options={options}
|
||||
value={selected}
|
||||
onChange={onSelect}
|
||||
/>
|
||||
|
||||
<div className="flex gap-4 mt-5 mb-8 items-center">
|
||||
<WarningIcon />
|
||||
<Label1 noMargin>
|
||||
To set up Twilio please read the instructions from our support
|
||||
portal.
|
||||
</Label1>
|
||||
</div>
|
||||
<SupportLinkButton
|
||||
link="https://support.lamassu.is/hc/en-us/articles/115001203951-Twilio-for-SMS"
|
||||
label="Twilio for SMS"
|
||||
/>
|
||||
|
||||
{selected === 'enable' && (
|
||||
<>
|
||||
<H4 noMargin>Enter credentials</H4>
|
||||
<FormRenderer
|
||||
xs={6}
|
||||
save={save}
|
||||
value={accounts.twilio}
|
||||
elements={twilio.elements}
|
||||
validationSchema={twilio.getValidationSchema(accounts.twilio)}
|
||||
buttonLabel={'Continue'}
|
||||
buttonClass={sharedClasses.formButton}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{selected !== 'enable' && (
|
||||
<Button
|
||||
size="lg"
|
||||
onClick={clickContinue}
|
||||
className={sharedClasses.button}>
|
||||
Continue
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Twilio
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
.content {
|
||||
width: 820px;
|
||||
}
|
||||
|
||||
.radioLabel {
|
||||
width: 280px;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
width: 1200px;
|
||||
height: 100px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-left: 8px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.info {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
import { useQuery, useMutation, gql } from "@apollo/client";
|
||||
import * as R from 'ramda'
|
||||
import React, { useState } from 'react'
|
||||
import { P, H4 } from 'src/components/typography'
|
||||
import { getElements, WalletSchema } from 'src/pages/Wallet/helper'
|
||||
|
||||
import { Button } from 'src/components/buttons'
|
||||
import { NamespacedTable as EditableTable } from 'src/components/editableTable'
|
||||
import { toNamespace, namespaces } from 'src/utils/config'
|
||||
|
||||
import classes from './Shared.module.css'
|
||||
const GET_INFO = gql`
|
||||
query getData {
|
||||
config
|
||||
accounts
|
||||
accountsConfig {
|
||||
code
|
||||
display
|
||||
class
|
||||
cryptos
|
||||
}
|
||||
cryptoCurrencies {
|
||||
code
|
||||
display
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const SAVE_CONFIG = gql`
|
||||
mutation Save($config: JSONObject, $accounts: JSONObject) {
|
||||
saveConfig(config: $config)
|
||||
saveAccounts(accounts: $accounts)
|
||||
}
|
||||
`
|
||||
|
||||
const AllSet = ({ data: currentData, doContinue }) => {
|
||||
const { data } = useQuery(GET_INFO)
|
||||
const [saveConfig] = useMutation(SAVE_CONFIG, {
|
||||
onCompleted: doContinue
|
||||
})
|
||||
|
||||
const [error, setError] = useState(false)
|
||||
|
||||
const coin = currentData?.coin
|
||||
|
||||
const accountsConfig = data?.accountsConfig
|
||||
const cryptoCurrencies = data?.cryptoCurrencies ?? []
|
||||
|
||||
const save = () => {
|
||||
const adjustedData = {
|
||||
zeroConfLimit: 0,
|
||||
...currentData
|
||||
}
|
||||
if (!WalletSchema.isValidSync(adjustedData)) return setError(true)
|
||||
|
||||
const withCoin = toNamespace(coin, R.omit('coin', adjustedData))
|
||||
const config = toNamespace(namespaces.WALLETS)(withCoin)
|
||||
setError(false)
|
||||
return saveConfig({ variables: { config } })
|
||||
}
|
||||
|
||||
const presentableData = R.pipe(
|
||||
R.omit(['coin', 'zeroConf', 'zeroConfLimit']),
|
||||
toNamespace(coin)
|
||||
)(currentData)
|
||||
|
||||
const presentableElements = R.filter(
|
||||
R.pipe(
|
||||
R.prop('name'),
|
||||
R.flip(R.includes)(['zeroConf', 'zeroConfLimit']),
|
||||
R.not()
|
||||
),
|
||||
getElements(cryptoCurrencies, accountsConfig, null, true)
|
||||
)
|
||||
|
||||
return (
|
||||
<>
|
||||
<H4 className={error && classes.error}>All set</H4>
|
||||
<P>
|
||||
These are your wallet settings. You can later edit these and add
|
||||
additional coins.
|
||||
</P>
|
||||
<EditableTable
|
||||
rowSize="lg"
|
||||
titleLg
|
||||
name="All set"
|
||||
namespaces={[coin]}
|
||||
data={presentableData}
|
||||
elements={presentableElements}
|
||||
/>
|
||||
<Button size="lg" onClick={save} className={classes.button}>
|
||||
Continue
|
||||
</Button>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default AllSet
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
import { useMutation, useQuery, gql } from "@apollo/client";
|
||||
import React, { useState } from 'react'
|
||||
import { P, H4 } from 'src/components/typography'
|
||||
import FormRenderer from 'src/pages/Services/FormRenderer'
|
||||
|
||||
import { SupportLinkButton, Button } from 'src/components/buttons'
|
||||
import { RadioGroup } from 'src/components/inputs'
|
||||
import blockcypherSchema from 'src/pages/Services/schemas/blockcypher'
|
||||
|
||||
import classes from './Shared.module.css'
|
||||
|
||||
const GET_CONFIG = gql`
|
||||
{
|
||||
accounts
|
||||
}
|
||||
`
|
||||
const SAVE_ACCOUNTS = gql`
|
||||
mutation SaveAccountsBC($accounts: JSONObject) {
|
||||
saveAccounts(accounts: $accounts)
|
||||
}
|
||||
`
|
||||
|
||||
const options = [
|
||||
{
|
||||
code: 'enable',
|
||||
display: 'I will enable cash-out'
|
||||
},
|
||||
{
|
||||
code: 'disable',
|
||||
display: "I won't enable cash-out"
|
||||
}
|
||||
]
|
||||
|
||||
const Blockcypher = ({ addData }) => {
|
||||
const { data } = useQuery(GET_CONFIG)
|
||||
const [saveConfig] = useMutation(SAVE_ACCOUNTS, {
|
||||
onCompleted: () => addData({ zeroConf: 'blockcypher' })
|
||||
})
|
||||
|
||||
const [selected, setSelected] = useState(null)
|
||||
const [error, setError] = useState(false)
|
||||
|
||||
const accounts = data?.accounts ?? []
|
||||
|
||||
const onSelect = e => {
|
||||
setSelected(e.target.value)
|
||||
setError(false)
|
||||
}
|
||||
|
||||
const save = blockcypher => {
|
||||
const accounts = { blockcypher }
|
||||
return saveConfig({ variables: { accounts } })
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<H4 className={error && classes.error}>Blockcypher</H4>
|
||||
<P>
|
||||
If you are enabling cash-out services, create a Blockcypher account.
|
||||
</P>
|
||||
<SupportLinkButton
|
||||
link="https://support.lamassu.is/hc/en-us/articles/115001209472-Blockcypher"
|
||||
label="Configuring Blockcypher"
|
||||
/>
|
||||
<RadioGroup
|
||||
labelClassName={classes.radioLabel}
|
||||
className={classes.radioGroup}
|
||||
options={options}
|
||||
value={selected}
|
||||
onChange={onSelect}
|
||||
/>
|
||||
<div className={classes.mdForm}>
|
||||
{selected === 'disable' && (
|
||||
<Button
|
||||
size="lg"
|
||||
onClick={() => addData({ zeroConf: 'none', zeroConfLimit: 0 })}
|
||||
className={classes.button}>
|
||||
Continue
|
||||
</Button>
|
||||
)}
|
||||
{selected === 'enable' && (
|
||||
<FormRenderer
|
||||
value={accounts.blockcypher}
|
||||
save={save}
|
||||
elements={blockcypherSchema.elements}
|
||||
validationSchema={blockcypherSchema.getValidationSchema}
|
||||
buttonLabel={'Continue'}
|
||||
buttonClass={classes.formButton}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Blockcypher
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
import { useQuery, gql } from "@apollo/client";
|
||||
import { Formik, Form, Field } from 'formik'
|
||||
import React, { useState } from 'react'
|
||||
import PromptWhenDirty from 'src/components/PromptWhenDirty'
|
||||
import { H4 } from 'src/components/typography'
|
||||
import * as Yup from 'yup'
|
||||
|
||||
import { Button } from 'src/components/buttons'
|
||||
import { RadioGroup } from 'src/components/inputs/formik'
|
||||
|
||||
import classes from './Shared.module.css'
|
||||
|
||||
const GET_CONFIG = gql`
|
||||
{
|
||||
cryptoCurrencies {
|
||||
code
|
||||
display
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const schema = Yup.object().shape({
|
||||
coin: Yup.string().required()
|
||||
})
|
||||
|
||||
const ChooseCoin = ({ addData }) => {
|
||||
const [error, setError] = useState(false)
|
||||
|
||||
const { data } = useQuery(GET_CONFIG)
|
||||
const cryptoCurrencies = data?.cryptoCurrencies ?? []
|
||||
|
||||
const onSubmit = it => {
|
||||
if (!schema.isValidSync(it)) return setError(true)
|
||||
|
||||
if (it.coin !== 'BTC') {
|
||||
return addData({ coin: it.coin, zeroConf: 'none', zeroConfLimit: 0 })
|
||||
}
|
||||
|
||||
addData(it)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<H4 className={error && classes.error}>
|
||||
Choose your first cryptocurrency
|
||||
</H4>
|
||||
|
||||
<Formik
|
||||
validateOnBlur={false}
|
||||
validateOnChange={false}
|
||||
enableReinitialize
|
||||
initialValues={{ coin: '' }}
|
||||
onSubmit={onSubmit}>
|
||||
<Form onChange={() => setError(false)}>
|
||||
<PromptWhenDirty />
|
||||
<Field
|
||||
component={RadioGroup}
|
||||
name="coin"
|
||||
labelClassName={classes.radioLabel}
|
||||
className={classes.radioGroup}
|
||||
options={cryptoCurrencies}
|
||||
/>
|
||||
{
|
||||
<Button size="lg" type="submit" className={classes.button}>
|
||||
Continue
|
||||
</Button>
|
||||
}
|
||||
</Form>
|
||||
</Formik>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default ChooseCoin
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
import { useQuery, useMutation, gql } from "@apollo/client";
|
||||
import { getEquivalentCode } from '@lamassu/coins/lightUtils'
|
||||
import * as R from 'ramda'
|
||||
import React, { useState } from 'react'
|
||||
import { H4, Info3 } from 'src/components/typography'
|
||||
import FormRenderer from 'src/pages/Services/FormRenderer'
|
||||
import WarningIcon from 'src/styling/icons/warning-icon/comet.svg?react'
|
||||
|
||||
import { Button, SupportLinkButton } from 'src/components/buttons'
|
||||
import { RadioGroup } from 'src/components/inputs'
|
||||
import _schema from 'src/pages/Services/schemas'
|
||||
|
||||
import classes from './Shared.module.css'
|
||||
import { getItems } from './getItems'
|
||||
|
||||
const GET_CONFIG = gql`
|
||||
{
|
||||
accounts
|
||||
accountsConfig {
|
||||
code
|
||||
display
|
||||
class
|
||||
cryptos
|
||||
}
|
||||
cryptoCurrencies {
|
||||
code
|
||||
display
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const SAVE_ACCOUNTS = gql`
|
||||
mutation Save($accounts: JSONObject) {
|
||||
saveAccounts(accounts: $accounts)
|
||||
}
|
||||
`
|
||||
|
||||
const isConfigurable = it =>
|
||||
!R.isNil(it) && !R.contains(it)(['mock-exchange', 'no-exchange'])
|
||||
|
||||
const ChooseExchange = ({ data: currentData, addData }) => {
|
||||
const { data } = useQuery(GET_CONFIG)
|
||||
const [saveAccounts] = useMutation(SAVE_ACCOUNTS, {
|
||||
onCompleted: () => submit()
|
||||
})
|
||||
|
||||
const [selected, setSelected] = useState(null)
|
||||
const [error, setError] = useState(false)
|
||||
|
||||
const schema = _schema()
|
||||
const accounts = data?.accounts ?? []
|
||||
const accountsConfig = data?.accountsConfig ?? []
|
||||
|
||||
const coin = getEquivalentCode(currentData.coin)
|
||||
const exchanges = getItems(accountsConfig, accounts, 'exchange', coin)
|
||||
|
||||
const submit = () => {
|
||||
if (!selected) return setError(true)
|
||||
addData({ exchange: selected })
|
||||
}
|
||||
|
||||
const saveExchange = name => exchange => {
|
||||
const accounts = { [name]: exchange }
|
||||
return saveAccounts({ variables: { accounts } })
|
||||
}
|
||||
|
||||
const onSelect = e => {
|
||||
setSelected(e.target.value)
|
||||
setError(false)
|
||||
}
|
||||
|
||||
const supportArticles = {
|
||||
kraken:
|
||||
'https://support.lamassu.is/hc/en-us/articles/115001206891-Kraken-trading',
|
||||
itbit:
|
||||
'https://support.lamassu.is/hc/en-us/articles/360026195032-itBit-trading',
|
||||
bitstamp:
|
||||
'https://support.lamassu.is/hc/en-us/articles/115001206911-Bitstamp-trading'
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classes.mdForm}>
|
||||
<H4 className={error && classes.error}>Choose your exchange</H4>
|
||||
<RadioGroup
|
||||
labelClassName={classes.radioLabel}
|
||||
className={classes.radioGroup}
|
||||
options={R.union(exchanges.filled, exchanges.unfilled)}
|
||||
value={selected}
|
||||
onChange={onSelect}
|
||||
/>
|
||||
{!isConfigurable(selected) && (
|
||||
<Button size="lg" onClick={submit} className={classes.button}>
|
||||
Continue
|
||||
</Button>
|
||||
)}
|
||||
{isConfigurable(selected) && (
|
||||
<>
|
||||
<div className={classes.infoMessage}>
|
||||
<WarningIcon />
|
||||
<Info3>
|
||||
Make sure you set up {schema[selected].name} to enter the
|
||||
necessary information below. Please follow the instructions on our
|
||||
support page if you haven’t.
|
||||
</Info3>
|
||||
</div>
|
||||
<SupportLinkButton
|
||||
link={supportArticles[selected]}
|
||||
label={`${schema[selected].name} trading`}
|
||||
/>
|
||||
|
||||
<H4 noMargin>Enter exchange information</H4>
|
||||
<FormRenderer
|
||||
value={accounts[selected]}
|
||||
save={saveExchange(selected)}
|
||||
elements={schema[selected].elements}
|
||||
validationSchema={schema[selected].getValidationSchema(accounts[selected])}
|
||||
buttonLabel={'Continue'}
|
||||
buttonClass={classes.formButton}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default ChooseExchange
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
import { useQuery, gql } from "@apollo/client";
|
||||
import { getEquivalentCode } from '@lamassu/coins/lightUtils'
|
||||
import * as R from 'ramda'
|
||||
import React, { useState } from 'react'
|
||||
import { H4 } from 'src/components/typography'
|
||||
|
||||
import { Button } from 'src/components/buttons'
|
||||
import { RadioGroup } from 'src/components/inputs'
|
||||
|
||||
import classes from './Shared.module.css'
|
||||
import { getItems } from './getItems'
|
||||
|
||||
const GET_CONFIG = gql`
|
||||
{
|
||||
accountsConfig {
|
||||
code
|
||||
display
|
||||
class
|
||||
cryptos
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const ChooseTicker = ({ data: currentData, addData }) => {
|
||||
const { data } = useQuery(GET_CONFIG)
|
||||
|
||||
const [selected, setSelected] = useState(null)
|
||||
const [error, setError] = useState(false)
|
||||
|
||||
const accounts = data?.accounts ?? []
|
||||
const accountsConfig = data?.accountsConfig ?? []
|
||||
|
||||
const coin = getEquivalentCode(currentData.coin)
|
||||
const tickers = getItems(accountsConfig, accounts, 'ticker', coin)
|
||||
|
||||
const submit = () => {
|
||||
if (!selected) return setError(true)
|
||||
addData({ ticker: selected })
|
||||
}
|
||||
|
||||
const onSelect = e => {
|
||||
setSelected(e.target.value)
|
||||
setError(false)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classes.mdForm}>
|
||||
<H4 className={error && classes.error}>Choose your ticker</H4>
|
||||
<RadioGroup
|
||||
labelClassName={classes.radioLabel}
|
||||
className={classes.radioGroup}
|
||||
options={R.union(tickers.filled, tickers.unfilled)}
|
||||
value={selected}
|
||||
onChange={onSelect}
|
||||
/>
|
||||
<Button size="lg" onClick={submit} className={classes.button}>
|
||||
Continue
|
||||
</Button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default ChooseTicker
|
||||
|
|
@ -0,0 +1,185 @@
|
|||
import { useQuery, useMutation, gql } from "@apollo/client";
|
||||
import * as R from 'ramda'
|
||||
import React, { useState } from 'react'
|
||||
import { H4, Info3 } from 'src/components/typography'
|
||||
import FormRenderer from 'src/pages/Services/FormRenderer'
|
||||
import WarningIcon from 'src/styling/icons/warning-icon/comet.svg?react'
|
||||
|
||||
import { Button, SupportLinkButton } from 'src/components/buttons'
|
||||
import { RadioGroup } from 'src/components/inputs'
|
||||
import _schema from 'src/pages/Services/schemas'
|
||||
import bitgo from 'src/pages/Services/schemas/singlebitgo'
|
||||
|
||||
import classes from './Shared.module.css'
|
||||
import { getItems } from './getItems'
|
||||
|
||||
const GET_CONFIG = gql`
|
||||
{
|
||||
accounts
|
||||
accountsConfig {
|
||||
code
|
||||
display
|
||||
class
|
||||
cryptos
|
||||
}
|
||||
cryptoCurrencies {
|
||||
code
|
||||
display
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const SAVE_ACCOUNTS = gql`
|
||||
mutation Save($accounts: JSONObject) {
|
||||
saveAccounts(accounts: $accounts)
|
||||
}
|
||||
`
|
||||
|
||||
const isConfigurable = it =>
|
||||
R.contains(it)(['infura', 'bitgo', 'trongrid', 'galoy'])
|
||||
|
||||
const isLocalHosted = it =>
|
||||
R.contains(it)([
|
||||
'bitcoind',
|
||||
'geth',
|
||||
'litecoind',
|
||||
'dashd',
|
||||
'zcashd',
|
||||
'bitcoincashd'
|
||||
])
|
||||
|
||||
const ChooseWallet = ({ data: currentData, addData }) => {
|
||||
// no need to fetch exchange config here
|
||||
const schema = _schema()
|
||||
const { data } = useQuery(GET_CONFIG)
|
||||
const [saveAccounts] = useMutation(SAVE_ACCOUNTS, {
|
||||
onCompleted: () => submit()
|
||||
})
|
||||
|
||||
const [selected, setSelected] = useState(null)
|
||||
const [error, setError] = useState(false)
|
||||
|
||||
const accounts = data?.accounts ?? []
|
||||
const accountsConfig = data?.accountsConfig ?? []
|
||||
|
||||
const coin = currentData.coin
|
||||
const wallets = getItems(accountsConfig, accounts, 'wallet', coin)
|
||||
|
||||
const saveWallet = name => wallet => {
|
||||
const accounts = { [name]: wallet }
|
||||
return saveAccounts({ variables: { accounts } })
|
||||
}
|
||||
|
||||
const submit = () => {
|
||||
if (!selected) return setError(true)
|
||||
addData({ wallet: selected })
|
||||
}
|
||||
|
||||
const onSelect = e => {
|
||||
setSelected(e.target.value)
|
||||
setError(false)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classes.mdForm}>
|
||||
<H4 className={error && classes.error}>Choose your wallet</H4>
|
||||
<RadioGroup
|
||||
labelClassName={classes.radioLabel}
|
||||
className={classes.radioGroup}
|
||||
options={R.union(wallets.filled, wallets.unfilled)}
|
||||
value={selected}
|
||||
onChange={onSelect}
|
||||
/>
|
||||
{isLocalHosted(selected) && (
|
||||
<>
|
||||
<div className={classes.infoMessage}>
|
||||
<WarningIcon />
|
||||
<Info3>
|
||||
To set up {selected} please read the node wallet instructions from
|
||||
our support portal.
|
||||
</Info3>
|
||||
</div>
|
||||
<SupportLinkButton
|
||||
link="https://support.lamassu.is/hc/en-us/articles/115001209552-Setting-up-your-node-wallets"
|
||||
label="Support article"
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{!isConfigurable(selected) && (
|
||||
<Button size="lg" onClick={submit} className={classes.button}>
|
||||
Continue
|
||||
</Button>
|
||||
)}
|
||||
{selected === 'bitgo' && (
|
||||
<>
|
||||
<div className={classes.infoMessage}>
|
||||
<WarningIcon />
|
||||
<Info3>
|
||||
Make sure you set up a BitGo wallet to enter the necessary
|
||||
information below. Please follow the instructions on our support
|
||||
page if you haven’t.
|
||||
</Info3>
|
||||
</div>
|
||||
<SupportLinkButton
|
||||
link="https://support.lamassu.is/hc/en-us/articles/360024455592-Setting-up-BitGo"
|
||||
label="Support article"
|
||||
/>
|
||||
<H4 noMargin>Enter wallet information</H4>
|
||||
<FormRenderer
|
||||
value={accounts.bitgo}
|
||||
save={saveWallet(selected)}
|
||||
elements={bitgo(coin).elements}
|
||||
validationSchema={bitgo(coin).validationSchema}
|
||||
buttonLabel={'Continue'}
|
||||
buttonClass={classes.formButton}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{selected === 'infura' && (
|
||||
<>
|
||||
<H4 noMargin>Enter wallet information</H4>
|
||||
<FormRenderer
|
||||
value={accounts.infura}
|
||||
save={saveWallet(selected)}
|
||||
elements={schema.infura.elements}
|
||||
validationSchema={schema.infura.getValidationSchema(
|
||||
accounts.infura
|
||||
)}
|
||||
buttonLabel={'Continue'}
|
||||
buttonClass={classes.formButton}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{selected === 'trongrid' && (
|
||||
<>
|
||||
<H4 noMargin>Enter wallet information</H4>
|
||||
<FormRenderer
|
||||
value={accounts.trongrid}
|
||||
save={saveWallet(selected)}
|
||||
elements={schema.trongrid.elements}
|
||||
validationSchema={schema.trongrid.getValidationSchema(
|
||||
accounts.trongrid
|
||||
)}
|
||||
buttonLabel={'Continue'}
|
||||
buttonClass={classes.formButton}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{selected === 'galoy' && (
|
||||
<>
|
||||
<H4 noMargin>Enter wallet information</H4>
|
||||
<FormRenderer
|
||||
value={accounts.galoy}
|
||||
save={saveWallet(selected)}
|
||||
elements={schema.galoy.elements}
|
||||
validationSchema={schema.galoy.getValidationSchema(accounts.galoy)}
|
||||
buttonLabel={'Continue'}
|
||||
buttonClass={classes.formButton}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default ChooseWallet
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
.radioGroup {
|
||||
flex-direction: row;
|
||||
width: 600px;
|
||||
}
|
||||
|
||||
.radioLabel {
|
||||
width: 150px;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
.mdForm {
|
||||
width: 385px;
|
||||
}
|
||||
|
||||
.infoMessage {
|
||||
display: flex;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.infoMessage > p {
|
||||
width: 330px;
|
||||
margin-top: 4px;
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
.actionButton {
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.actionButtonLink {
|
||||
text-decoration: none;
|
||||
color: var(--zodiac);
|
||||
}
|
||||
|
||||
.error {
|
||||
color: var(--tomato);
|
||||
}
|
||||
|
||||
.button {
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.formButton {
|
||||
margin: 24px 0 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
import * as R from 'ramda'
|
||||
import React, { useState } from 'react'
|
||||
import Sidebar, { Stepper } from 'src/components/layout/Sidebar'
|
||||
import TitleSection from 'src/components/layout/TitleSection'
|
||||
|
||||
import AllSet from './AllSet'
|
||||
import Blockcypher from './Blockcypher'
|
||||
import ChooseCoin from './ChooseCoin'
|
||||
import ChooseExchange from './ChooseExchange'
|
||||
import ChooseTicker from './ChooseTicker'
|
||||
import ChooseWallet from './ChooseWallet'
|
||||
|
||||
const steps = [
|
||||
{
|
||||
label: 'Choose cryptocurrency',
|
||||
component: ChooseCoin
|
||||
},
|
||||
{
|
||||
label: 'Choose wallet',
|
||||
component: ChooseWallet
|
||||
},
|
||||
{
|
||||
label: 'Choose ticker',
|
||||
component: ChooseTicker
|
||||
},
|
||||
{
|
||||
label: 'Exchange',
|
||||
component: ChooseExchange
|
||||
},
|
||||
{
|
||||
label: 'Blockcypher',
|
||||
component: Blockcypher
|
||||
},
|
||||
{
|
||||
label: 'All set',
|
||||
component: AllSet
|
||||
}
|
||||
]
|
||||
|
||||
const Wallet = ({ doContinue }) => {
|
||||
const [step, setStep] = useState(0)
|
||||
const [data, setData] = useState({})
|
||||
|
||||
const mySteps = data?.coin === 'BTC' ? steps : R.remove(4, 1, steps)
|
||||
|
||||
const Component = mySteps[step].component
|
||||
|
||||
const addData = it => {
|
||||
setData(R.merge(data, it))
|
||||
setStep(step + 1)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="w-[1132px] h-full mx-auto flex-1 flex flex-col">
|
||||
<div className="flex justify-between items-center">
|
||||
<TitleSection title="Wallet settings"></TitleSection>
|
||||
</div>
|
||||
<div className="flex flex-1 flex-row">
|
||||
<Sidebar>
|
||||
{mySteps.map((it, idx) => (
|
||||
<Stepper key={idx} step={step} it={it} idx={idx} steps={mySteps} />
|
||||
))}
|
||||
</Sidebar>
|
||||
<div className="ml-12">
|
||||
<Component data={data} addData={addData} doContinue={doContinue} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Wallet
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
import * as R from 'ramda'
|
||||
|
||||
import _schema from 'src/pages/Services/schemas'
|
||||
|
||||
const contains = crypto => R.compose(R.contains(crypto), R.prop('cryptos'))
|
||||
const sameClass = type => R.propEq('class', type)
|
||||
const filterConfig = (crypto, type) =>
|
||||
R.filter(it => sameClass(type)(it) && contains(crypto)(it))
|
||||
export const getItems = (accountsConfig, accounts, type, crypto) => {
|
||||
const schema = _schema()
|
||||
const fConfig = filterConfig(crypto, type)(accountsConfig)
|
||||
const find = code => accounts && accounts[code]
|
||||
|
||||
const [filled, unfilled] = R.partition(({ code }) => {
|
||||
const account = find(code)
|
||||
if (!schema[code]) return true
|
||||
|
||||
const { getValidationSchema } = schema[code]
|
||||
return getValidationSchema(account).isValidSync(account)
|
||||
})(fConfig)
|
||||
|
||||
return { filled, unfilled }
|
||||
}
|
||||
22
packages/admin-ui/src/pages/Wizard/components/Welcome.jsx
Normal file
22
packages/admin-ui/src/pages/Wizard/components/Welcome.jsx
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import React from 'react'
|
||||
import { H1, P } from 'src/components/typography'
|
||||
|
||||
import { Button } from 'src/components/buttons'
|
||||
|
||||
function Welcome({ doContinue }) {
|
||||
return (
|
||||
<div className="text-center flex flex-col items-center justify-center w-full h-full">
|
||||
<H1 className="text-5xl">Welcome to the Lamassu Admin</H1>
|
||||
<P className="text-2xl mb-14 text-comet">
|
||||
To get you started, we’ve put together a wizard that will
|
||||
<br />
|
||||
help set up what you need before pairing your machines.
|
||||
</P>
|
||||
<Button size="xl" onClick={doContinue}>
|
||||
Get started
|
||||
</Button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Welcome
|
||||
Loading…
Add table
Add a link
Reference in a new issue