style updates

This commit is contained in:
fmtabbara
2021-11-29 22:11:28 +00:00
parent a85a67199a
commit d69cb47c6c
10 changed files with 141 additions and 419 deletions
+36 -19
View File
@@ -1,22 +1,21 @@
import React, { useContext } from 'react'
import React, { useContext, useEffect } from 'react'
import {
AppBar as MuiAppBar,
Divider,
Grid,
IconButton,
List,
ListItem,
ListItemText,
Toolbar,
Typography,
useMediaQuery,
} from '@mui/material'
import { ExitToApp } from '@mui/icons-material'
import { ClientContext } from '../context/main'
import { Box } from '@mui/system'
import { Logout } from '@mui/icons-material'
import { ClientContext } from '../context/main'
import { CopyToClipboard } from '.'
export const AppBar = () => {
const { userBalance, logOut, clientDetails } = useContext(ClientContext)
const matches = useMediaQuery('(min-width: 769px)')
return (
<MuiAppBar
@@ -37,20 +36,33 @@ export const AppBar = () => {
secondaryText={userBalance.balance?.printable_balance}
/>
</Grid>
<Divider orientation="vertical" variant="middle" flexItem />
<Grid item>
<AppBarItem
primaryText="Address"
secondaryText={clientDetails?.client_address}
Action={
<CopyToClipboard text={clientDetails?.client_address} />
}
/>
</Grid>
{matches && (
<>
<Divider
orientation="vertical"
variant="middle"
flexItem
sx={{ mr: 1 }}
/>
<Grid item>
<AppBarItem
primaryText="Address"
secondaryText={clientDetails?.client_address}
Action={
<CopyToClipboard
text={clientDetails?.client_address}
iconButton
/>
}
/>
</Grid>
</>
)}
</Grid>
<Grid item>
<IconButton onClick={logOut} sx={{ color: 'nym.background.dark' }}>
<ExitToApp />
<Logout />
</IconButton>
</Grid>
</Grid>
@@ -65,11 +77,16 @@ const AppBarItem: React.FC<{
Action?: React.ReactNode
}> = ({ primaryText, secondaryText = '', Action }) => {
return (
<Box sx={{ p: 1 }}>
<Box sx={{ p: 1, mr: 1 }}>
<Typography variant="body2" component="span" sx={{ color: 'grey.600' }}>
{primaryText}:
</Typography>{' '}
<Typography variant="body2" component="span" color="nym.background.dark">
<Typography
variant="body2"
component="span"
color="nym.background.dark"
sx={{ mr: 1 }}
>
{secondaryText}
</Typography>
{Action}
+52 -15
View File
@@ -1,14 +1,16 @@
import React, { useEffect, useState } from 'react'
import { IconButton, Tooltip } from '@mui/material'
import { Button, IconButton, Tooltip } from '@mui/material'
import { Check, ContentCopy } from '@mui/icons-material'
import { clipboard } from '@tauri-apps/api'
export const CopyToClipboard = ({
text = '',
light,
iconButton,
}: {
text?: string
light?: boolean
iconButton?: boolean
}) => {
const [copied, setCopied] = useState(false)
@@ -22,24 +24,59 @@ export const CopyToClipboard = ({
}
useEffect(() => {
let timer: NodeJS.Timeout
if (copied) {
setTimeout(() => {
timer = setTimeout(() => {
setCopied(false)
}, 1000)
}, 2000)
}
return () => clearTimeout(timer)
}, [copied])
if (iconButton)
return (
<Tooltip title={!copied ? 'Copy' : 'Copied!'} leaveDelay={500}>
<IconButton
onClick={() => handleCopy(text)}
size="small"
sx={{
color: (theme) =>
light
? theme.palette.common.white
: theme.palette.nym.background.dark,
}}
>
{!copied ? (
<ContentCopy fontSize="small" />
) : (
<Check color="success" />
)}
</IconButton>
</Tooltip>
)
return (
<Tooltip title={!copied ? 'Copy' : 'Copied!'} leaveDelay={500}>
<IconButton
onClick={() => handleCopy(text)}
size="small"
sx={{
color: (theme) =>
light ? theme.palette.common.white : theme.palette.grey[600],
}}
>
{!copied ? <ContentCopy fontSize="small" /> : <Check color="success" />}
</IconButton>
</Tooltip>
<Button
variant="outlined"
color="inherit"
sx={{
color: (theme) =>
light
? theme.palette.common.white
: theme.palette.nym.background.dark,
borderColor: (theme) =>
light
? theme.palette.common.white
: theme.palette.nym.background.dark,
}}
onClick={() => handleCopy(text)}
endIcon={
copied && (
<Check sx={{ color: (theme) => theme.palette.success.light }} />
)
}
>
{!copied ? 'Copy' : 'Copied'}
</Button>
)
}
+21 -25
View File
@@ -2,59 +2,58 @@ import React, { useContext, useEffect } from 'react'
import { Link, useLocation } from 'react-router-dom'
import { List, ListItem, ListItemIcon, ListItemText } from '@mui/material'
import {
AccountBalanceWalletRounded,
AccountBalanceWalletOutlined,
ArrowBack,
ArrowForward,
AttachMoney,
Cancel,
HowToVote,
CancelOutlined,
HowToVoteOutlined,
MoneyOff,
Description,
Settings,
} from '@mui/icons-material'
import { ADMIN_ADDRESS, ClientContext } from '../context/main'
let routesSchema = [
{
label: 'Balance',
route: '/balance',
Icon: <AccountBalanceWalletRounded />,
Icon: AccountBalanceWalletOutlined,
},
{
label: 'Send',
route: '/send',
Icon: <ArrowForward />,
Icon: ArrowForward,
},
{
label: 'Receive',
route: '/receive',
Icon: <ArrowBack />,
Icon: ArrowBack,
},
{
label: 'Bond',
route: '/bond',
Icon: <AttachMoney />,
Icon: AttachMoney,
},
{
label: 'Unbond',
route: '/unbond',
Icon: <MoneyOff />,
Icon: MoneyOff,
},
{
label: 'Delegate',
route: '/delegate',
Icon: <HowToVote />,
Icon: HowToVoteOutlined,
},
{
label: 'Undelegate',
route: '/undelegate',
Icon: <Cancel />,
Icon: CancelOutlined,
},
]
export const Nav = () => {
const { clientDetails, handleShowAdmin, logOut } = useContext(ClientContext)
const { clientDetails, handleShowAdmin } = useContext(ClientContext)
const location = useLocation()
useEffect(() => {
@@ -62,7 +61,7 @@ export const Nav = () => {
routesSchema.push({
label: 'Docs',
route: '/docs',
Icon: <Description />,
Icon: Description,
})
}
}, [])
@@ -72,30 +71,27 @@ export const Nav = () => {
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
justifyContent: 'flex-start',
}}
>
<List>
{routesSchema.map((r, i) => (
<ListItem button component={Link} to={r.route} key={i}>
<List disablePadding>
{routesSchema.map(({ Icon, route, label }, i) => (
<ListItem disableGutters component={Link} to={route} key={i}>
<ListItemIcon
sx={{
minWidth: 30,
color:
location.pathname === r.route
? 'primary.main'
: 'common.white',
location.pathname === route ? 'primary.main' : 'common.white',
}}
>
{r.Icon}
<Icon sx={{ fontSize: 20 }} />
</ListItemIcon>
<ListItemText
sx={{
color:
location.pathname === r.route
? 'primary.main'
: 'common.white',
location.pathname === route ? 'primary.main' : 'common.white',
}}
primary={r.label}
primary={label}
/>
</ListItem>
))}
+4 -11
View File
@@ -1,5 +1,5 @@
import React from 'react'
import { Box, Divider } from '@mui/material'
import { Box } from '@mui/material'
import { Nav } from '../components'
import Logo from '../images/logo-background.svg'
import { AppBar } from '../components/AppBar'
@@ -20,21 +20,14 @@ export const ApplicationLayout: React.FC = ({ children }) => {
sx={{
background: '#121726',
overflow: 'auto',
p: [4, 5],
}}
>
<Box sx={{ display: 'flex', justifyContent: 'center', marginTop: 6 }}>
<Box sx={{ mb: 3 }}>
<img src={Logo} style={{ width: 45 }} />
</Box>
<Divider
light
variant="middle"
sx={{ bgcolor: (theme) => theme.palette.grey[100], marginTop: 6 }}
/>
<Box sx={{ marginTop: 7 }}>
<Nav />
</Box>
<Box />
<Nav />
</Box>
<Box
sx={{
+2 -22
View File
@@ -1,13 +1,6 @@
import React, { useContext } from 'react'
import {
Alert,
Button,
CircularProgress,
Grid,
IconButton,
} from '@mui/material'
import { Alert, Grid } from '@mui/material'
import { Box } from '@mui/system'
import { Refresh } from '@mui/icons-material'
import { NymCard } from '../components'
import { Layout } from '../layouts'
@@ -16,22 +9,9 @@ import { ClientContext } from '../context/main'
export const Balance = () => {
const { userBalance } = useContext(ClientContext)
const RefreshAction = () => (
<IconButton
disabled={userBalance.isLoading}
onClick={userBalance.fetchBalance}
>
{userBalance.isLoading ? <CircularProgress size={20} /> : <Refresh />}
</IconButton>
)
return (
<Layout>
<NymCard
title="Balance"
data-testid="check-balance"
Action={<RefreshAction />}
>
<NymCard title="Balance" data-testid="check-balance">
<Grid container direction="column" spacing={2}>
<Grid item>
{userBalance.error && (
-312
View File
@@ -1,312 +0,0 @@
import React, { useContext, useState } from 'react'
import {
Box,
Alert,
TextField,
CircularProgress,
Button,
Typography,
Grid,
Link,
Card,
Divider,
} from '@mui/material'
import { ArrowBack, CheckCircleOutline } from '@mui/icons-material'
import logo from '../images/logo-background.svg'
import logo_alt from '../images/logo.png'
import { ClientContext } from '../context/main'
import { createAccount, signInWithMnemonic } from '../requests'
import { TCreateAccount } from '../types'
import { CopyToClipboard } from '../components'
export const SignIn = () => {
const [showCreateAccount, setShowCreateAccount] = useState(false)
return (
<Box
sx={{
height: '100vh',
width: '100vw',
display: 'grid',
gridTemplateColumns: '400px auto',
gridTemplateRows: '100%',
gridColumnGap: '0px',
gridRowGap: '0px',
}}
>
<Box
sx={{
gridArea: '1 / 1 / 2 / 2',
background: '#121726',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
>
<img src={logo} style={{ width: 100 }} />
</Box>
<Box
sx={{
gridArea: '1 / 2 / 2 / 3',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
>
{showCreateAccount ? (
<CreateAccountContent
showSignIn={() => setShowCreateAccount(false)}
/>
) : (
<SignInContent showCreateAccount={() => setShowCreateAccount(true)} />
)}
</Box>
</Box>
)
}
const SignInContent = ({
showCreateAccount,
}: {
showCreateAccount: () => void
}) => {
const [mnemonic, setMnemonic] = useState<string>('')
const [inputError, setInputError] = useState<string>()
const [isLoading, setIsLoading] = useState(false)
const { logIn } = useContext(ClientContext)
const handleSignIn = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault()
setIsLoading(true)
setInputError(undefined)
try {
const res = await signInWithMnemonic(mnemonic || '')
setIsLoading(false)
logIn(res)
} catch (e: any) {
setIsLoading(false)
setInputError(e)
}
}
return (
<SignInCard>
<>
<Typography variant="h4" data-testid="sign-in">
Sign in
</Typography>
<form noValidate onSubmit={handleSignIn}>
<Grid container direction="column" spacing={1}>
<Grid item>
<TextField
value={mnemonic}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
setMnemonic(e.target.value)
}
size="medium"
variant="outlined"
margin="normal"
required
fullWidth
id="mnemonic"
label="BIP-39 Mnemonic"
name="mnemonic"
autoComplete="mnemonic"
autoFocus
disabled={isLoading}
/>
</Grid>
<Grid item>
<Button
fullWidth
variant="contained"
color="primary"
type="submit"
disabled={isLoading}
endIcon={isLoading && <CircularProgress size={20} />}
disableElevation
size="large"
>
{!isLoading ? 'Sign In' : 'Signing in'}
</Button>
</Grid>
{inputError && (
<Grid item sx={{ mt: 1 }}>
<Alert severity="error">{inputError}</Alert>
</Grid>
)}
<Grid item sx={{ mt: 1 }}>
<Typography variant="body2" component="span">
Don't have an account?
</Typography>{' '}
<Link href="#" onClick={showCreateAccount}>
Create one
</Link>
</Grid>
</Grid>
</form>
</>
</SignInCard>
)
}
const SignInCard: React.FC = ({ children }) => {
return (
<>
<Card
sx={{
width: 600,
p: [6, 10],
position: 'relative',
minHeight: 350,
}}
>
<img
src={logo_alt}
style={{
position: 'absolute',
width: 425,
filter: 'grayscale(100%)',
opacity: 0.1,
top: '50%',
left: '50%',
transform: 'translate(0%, -50%)',
}}
/>
{children}
</Card>
</>
)
}
const CreateAccountContent = ({ showSignIn }: { showSignIn: () => void }) => {
const [accountDetails, setAccountDetails] = useState<TCreateAccount>()
const [isLoading, setIsLoading] = useState(false)
const [error, setError] = useState<Error>()
const handleCreateAccount = async () => {
setIsLoading(true)
setError(undefined)
try {
const res = await createAccount()
setTimeout(() => {
setAccountDetails(res)
setIsLoading(false)
}, 2500)
} catch (e: any) {
setError(e)
}
}
return (
<SignInCard>
<Typography variant="h4">Create wallet</Typography>
<Typography color="textSecondary">
Create a new wallet to start using the Nym network
</Typography>
<Grid container direction="column" spacing={3} sx={{ mt: 3 }}>
<Grid item container justifyContent="center">
{isLoading && <CircularProgress size={48} />}
{!isLoading && accountDetails && (
<>
<Box
sx={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
mb: 4,
}}
>
<CheckCircleOutline
sx={{
fontSize: 50,
color: 'success.main',
mb: 1,
}}
/>
<Typography>Wallet setup complete</Typography>
</Box>
<Alert
severity="info"
sx={{ mb: 2 }}
data-testid="mnemonic-warning"
>
Please store your <strong>mnemonic</strong> in a safe place.
You'll need it to access your wallet
</Alert>
<Card
variant="outlined"
sx={{
width: '100%',
p: 2,
}}
>
<Grid container direction="column" spacing={1}>
<Grid item>
<Typography sx={{ color: 'grey[600]' }}>
Mnemonic
</Typography>
</Grid>
<Grid item>
<Typography data-testid="mnemonic-phrase">
{accountDetails.mnemonic}
</Typography>
<Box sx={{ display: 'flex', justifyContent: 'flex-end' }}>
<CopyToClipboard text={accountDetails.mnemonic} />
</Box>
</Grid>
<Grid item>
<Divider light />
</Grid>
<Grid item>
<Typography sx={{ color: 'grey[600]' }}>Address</Typography>
</Grid>
<Grid item>
<Typography data-testid="wallet-address">
{accountDetails.client_address}
</Typography>
</Grid>
</Grid>
</Card>
</>
)}
</Grid>
{error && (
<Grid item sx={{ mt: 1 }}>
<Alert severity="error" data-testid="error">
{error}
</Alert>
</Grid>
)}
<Grid item>
{!accountDetails && (
<Button
onClick={handleCreateAccount}
fullWidth
variant="contained"
color="primary"
type="submit"
data-testid="create-button"
disableElevation
sx={{ mb: 1 }}
disabled={isLoading}
>
Create
</Button>
)}
<Button
fullWidth
variant="text"
onClick={showSignIn}
data-testid="sign-in-button"
startIcon={<ArrowBack />}
>
Sign in
</Button>
</Grid>
</Grid>
</SignInCard>
)
}
@@ -11,6 +11,7 @@ import {
Typography,
} from '@mui/material'
import { Box } from '@mui/system'
import { ArrowBack } from '@mui/icons-material'
import { createAccount } from '../../requests'
import { TCreateAccount } from '../../types'
import logo from '../../images/logo-background.svg'
@@ -52,14 +53,16 @@ export const CreateAccountContent: React.FC<{ showSignIn: () => void }> = ({
<Typography sx={{ color: 'common.white' }} variant="h6">
Account setup complete!
</Typography>
<Alert severity="info" variant="outlined">
<Box
sx={{ textAlign: 'center', color: 'info.light' }}
data-testid="mnemonic-warning"
>
<Alert
severity="info"
variant="outlined"
sx={{ color: 'info.light' }}
data-testid="mnemonic-warning"
>
<Typography>
Please store your mnemonic in a safe place. You'll need it to access
your account!
</Box>
</Typography>
</Alert>
<Card
variant="outlined"
@@ -77,9 +80,7 @@ export const CreateAccountContent: React.FC<{ showSignIn: () => void }> = ({
</CardActions>
</Card>
<Box sx={{ textAlign: 'center' }}>
<Typography sx={{ color: 'common.white' }} variant="body2">
Account address:
</Typography>
<Typography sx={{ color: 'common.white' }}>Address:</Typography>
<Typography sx={{ color: 'common.white' }} data-testid="wallet-address">
{accountDetails?.client_address}
</Typography>
@@ -93,8 +94,11 @@ export const CreateAccountContent: React.FC<{ showSignIn: () => void }> = ({
variant="contained"
onClick={showSignIn}
data-testid="sign-in-button"
startIcon={<ArrowBack />}
size="large"
sx={{ width: 360 }}
>
Back to sign in
Back to Sign in
</Button>
</Stack>
)
+2
View File
@@ -13,6 +13,7 @@ export const SignIn = () => {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
overflow: 'auto',
bgcolor: (theme) => theme.palette.nym.background.dark,
}}
>
@@ -21,6 +22,7 @@ export const SignIn = () => {
width: 500,
display: 'flex',
justifyContent: 'center',
margin: 'auto',
}}
>
{showCreateAccount ? (
+5 -4
View File
@@ -9,10 +9,10 @@ import {
Typography,
Alert,
} from '@mui/material'
import { styled } from '@mui/styles'
import logo from '../../images/logo-background.svg'
import { signInWithMnemonic } from '../../requests'
import { ClientContext } from '../../context/main'
import { styled } from '@mui/styles'
export const SignInContent: React.FC<{ showCreateAccount: () => void }> = ({
showCreateAccount,
@@ -40,13 +40,13 @@ export const SignInContent: React.FC<{ showCreateAccount: () => void }> = ({
}
return (
<Stack spacing={3} alignItems="center" sx={{ width: '100%' }}>
<Stack spacing={3} alignItems="center" sx={{ width: '80%' }}>
<img src={logo} style={{ width: 80 }} />
<Typography sx={{ color: 'common.white' }}>
Enter Mnemonic and sign in
</Typography>
<Grid container direction="column" spacing={1}>
<Grid item>
<Grid container direction="column" spacing={3}>
<Grid item style={{ paddingTop: 0 }}>
<StyledInput
value={mnemonic}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
@@ -63,6 +63,7 @@ export const SignInContent: React.FC<{ showCreateAccount: () => void }> = ({
autoComplete="mnemonic"
autoFocus
disabled={isLoading}
sx={{ m: 0 }}
/>
</Grid>
<Grid item>
+5 -1
View File
@@ -164,7 +164,11 @@ export const getDesignTokens = (mode: PaletteMode): ThemeOptions => {
'Helvetica Neue',
].join(','),
fontSize: 14,
fontWeightRegular: 600,
fontWeightRegular: 500,
button: {
textTransform: 'none',
fontWeight: '600',
},
},
shape: {
borderRadius: 8,