Feat: New styleguide, table component and screen

This commit is contained in:
Rafael Taranto 2019-11-11 15:34:14 +00:00
parent c100c11a2f
commit 8b4a1ff23f
20 changed files with 309 additions and 287 deletions

View file

@ -4737,7 +4737,8 @@
"asap": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
"integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
"integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=",
"dev": true
},
"asn1": {
"version": "0.2.4",
@ -7705,6 +7706,7 @@
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.2.3.tgz",
"integrity": "sha512-CQBmD0+QGgTaxDL3OX1IDXYqjkp2It4RIbcb99jS6AEg27Ga+a9G3JtK6SIu0HBwPLZlmwt9F7UwWA4Bn92Rag==",
"dev": true,
"requires": {
"fbjs": "^0.8.0",
"gud": "^1.0.0"
@ -8800,6 +8802,7 @@
"version": "0.1.12",
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
"integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
"dev": true,
"requires": {
"iconv-lite": "~0.4.13"
}
@ -10278,6 +10281,7 @@
"version": "0.8.17",
"resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz",
"integrity": "sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=",
"dev": true,
"requires": {
"core-js": "^1.0.0",
"isomorphic-fetch": "^2.1.1",
@ -10291,12 +10295,14 @@
"core-js": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
"integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY="
"integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=",
"dev": true
},
"promise": {
"version": "7.3.1",
"resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
"integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
"dev": true,
"requires": {
"asap": "~2.0.3"
}
@ -10618,17 +10624,16 @@
"dev": true
},
"formik": {
"version": "1.5.8",
"resolved": "https://registry.npmjs.org/formik/-/formik-1.5.8.tgz",
"integrity": "sha512-fNvPe+ddbh+7xiByT25vuso2p2hseG/Yvuj211fV1DbCjljUEG9OpgRpcb7g7O3kxHX/q31cbZDzMxJXPWSNwA==",
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/formik/-/formik-2.0.3.tgz",
"integrity": "sha512-kYBvcxlsYSncY8OiJHD49C0UmoWXbgmIc9V1g3N1WwBJ7SMLk34QpcJDgroYd42K1cH+mSJlXhB7PlgTXTzlWg==",
"requires": {
"create-react-context": "^0.2.2",
"deepmerge": "^2.1.1",
"hoist-non-react-statics": "^3.3.0",
"lodash": "^4.17.14",
"lodash-es": "^4.17.14",
"prop-types": "^15.6.1",
"react-fast-compare": "^2.0.1",
"scheduler": "^0.14.0",
"tiny-warning": "^1.0.2",
"tslib": "^1.9.3"
},
@ -10637,6 +10642,15 @@
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz",
"integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA=="
},
"scheduler": {
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.14.0.tgz",
"integrity": "sha512-9CgbS06Kki2f4R9FjLSITjZo5BZxPsryiRNyL3LpvrM9WxcVmhlqAOc9E+KQbeI2nqej4JIIbOsfdL51cNb4Iw==",
"requires": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1"
}
}
}
},
@ -11476,6 +11490,7 @@
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
"dev": true,
"requires": {
"safer-buffer": ">= 2.1.2 < 3"
}
@ -11975,7 +11990,8 @@
"is-stream": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
"dev": true
},
"is-svg": {
"version": "3.0.0",
@ -12041,6 +12057,7 @@
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz",
"integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=",
"dev": true,
"requires": {
"node-fetch": "^1.0.1",
"whatwg-fetch": ">=0.10.0"
@ -14856,6 +14873,7 @@
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
"integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
"dev": true,
"requires": {
"encoding": "^0.1.11",
"is-stream": "^1.0.1"
@ -19994,7 +20012,8 @@
"safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"dev": true
},
"sane": {
"version": "4.1.0",
@ -20318,7 +20337,8 @@
"setimmediate": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
"integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU="
"integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
"dev": true
},
"setprototypeof": {
"version": "1.1.1",
@ -22019,7 +22039,8 @@
"ua-parser-js": {
"version": "0.7.20",
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.20.tgz",
"integrity": "sha512-8OaIKfzL5cpx8eCMAhhvTlft8GYF8b2eQr6JkCyVdrgjcytyOmPCXrqXFcUnhonRpLlh5yxEZVohm6mzaowUOw=="
"integrity": "sha512-8OaIKfzL5cpx8eCMAhhvTlft8GYF8b2eQr6JkCyVdrgjcytyOmPCXrqXFcUnhonRpLlh5yxEZVohm6mzaowUOw==",
"dev": true
},
"uglify-js": {
"version": "3.4.9",
@ -22849,7 +22870,8 @@
"whatwg-fetch": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz",
"integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q=="
"integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==",
"dev": true
},
"whatwg-mimetype": {
"version": "2.3.0",

View file

@ -11,7 +11,7 @@
"classnames": "2.2.6",
"downshift": "3.3.4",
"file-saver": "2.0.2",
"formik": "1.5.8",
"formik": "2.0.3",
"jss-plugin-extend": "^10.0.0",
"lodash": "4.17.15",
"moment": "2.24.0",

View file

@ -62,7 +62,9 @@ const Header = memo(({ tree }) => {
className={classnames(classes.link, classes.whiteLink)}
activeClassName={classes.activeLink}
>
<span className={classes.forceSize} forcesize={it.label}>
{it.label}
</span>
</NavLink>
</li>
))}

View file

@ -11,10 +11,10 @@ import {
import typographyStyles from './typography/styles'
const { tl2 } = typographyStyles
const { tl2, p } = typographyStyles
let headerHeight = spacer * 7
let subheaderHeight = spacer * 6
let subheaderHeight = spacer * 5
if (version === 8) {
headerHeight = spacer * 8
@ -51,11 +51,15 @@ export default {
padding: `0 ${spacer * 2.5}px`
},
link: {
extend: tl2,
extend: p,
textDecoration: 'none',
border: 'none',
color: white,
backgroundColor: 'transparent',
'&:hover': {
extend: tl2,
color: white
},
'&:hover::after': {
width: '50%',
marginLeft: '-25%'
@ -75,7 +79,21 @@ export default {
transition: 'all 0.2s cubic-bezier(0.95, 0.1, 0.45, 0.94)'
}
},
forceSize: {
display: 'inline-block',
textAlign: 'center',
'&:after': {
display: 'block',
content: 'attr(forcesize)',
fontWeight: 700,
height: 0,
overflow: 'hidden',
visibility: 'hidden'
}
},
activeLink: {
extend: tl2,
color: white,
'&::after': {
width: '50%',
marginLeft: '-25%'

View file

@ -6,19 +6,25 @@ import styles from './Sidebar.styles'
const useStyles = makeStyles(styles)
const Logs = ({ data, displayName, isSelected, onClick, children }) => {
const Logs = ({ data, displayName, isSelected, onClick, children, itemRender }) => {
const classes = useStyles()
return (
<div className={classes.sidebar}>
{data &&
data.map((it, idx) => (
<p
<div
key={idx}
className={classnames(isSelected(it) ? classes.activeLink : '', classes.link)}
className={classnames({
[classes.activeLink]: isSelected(it),
[classes.customRenderActiveLink]: itemRender && isSelected(it),
[classes.customRenderLink]: itemRender,
[classes.link]: true
})}
onClick={() => onClick(it)}
>
{displayName(it)}
</p>
{itemRender ? itemRender(it) : displayName(it)}
</div>
))}
{children}
</div>

View file

@ -1,6 +1,10 @@
import { respondTo } from '../styling/helpers'
import { primaryColor, spacer, placeholderColor, zircon, xxl } from '../styling/variables'
import typographyStyles from './typography/styles'
const { tl2 } = typographyStyles
const sidebarColor = zircon
export default {
@ -12,7 +16,7 @@ export default {
boxShadow: `-500px 0px 0px 0px ${sidebarColor}`,
borderRadius: '0 20px 0 0',
alignItems: 'flex-end',
padding: spacer * 2.5,
padding: spacer * 3,
flexDirection: 'column',
[respondTo(xxl)]: {
width: 'auto',
@ -23,9 +27,10 @@ export default {
},
link: {
extend: tl2,
position: 'relative',
color: placeholderColor,
marginRight: 24,
margin: '12px 24px 12px 0',
cursor: 'pointer',
'&:hover::after': {
height: '140%'
@ -50,5 +55,18 @@ export default {
'&::after': {
height: '140%'
}
},
customRenderLink: {
'&:hover::after': {
height: '100%'
},
'&:after': {
bottom: 0
}
},
customRenderActiveLink: {
'&::after': {
height: '100%'
}
}
}

View file

@ -9,7 +9,7 @@ import {
import typographyStyles from '../typography/styles'
const { label } = typographyStyles
const { p } = typographyStyles
const colors = (color1, color2, color3) => {
return {
@ -25,7 +25,7 @@ const colors = (color1, color2, color3) => {
export default {
actionButton: {
extend: label,
extend: p,
cursor: 'pointer',
border: 'none',
height: 24,

View file

@ -1,6 +1,6 @@
import React, { useState } from 'react'
import { identity } from 'lodash/fp'
import { FastField } from 'formik'
import React, { useState, memo } from 'react'
import { identity, isEmpty } from 'lodash/fp'
import { Form, Formik, FastField, useFormikContext } from 'formik'
import {
Td,
@ -13,18 +13,24 @@ const getField = (name, component, props = {}) => (
<FastField name={name} component={component} {...props} />
)
const ERow = ({ elements, cancel, save, value }) => {
const ERow = memo(({ elements }) => {
const { values, submitForm, resetForm, errors } = useFormikContext()
const [editing, setEditing] = useState(false)
const innerSave = () => {
submitForm()
}
const innerCancel = () => {
setEditing(false)
cancel()
resetForm()
}
return (
<Tr>
{elements.map(({ name, input, size, view = identity, inputProps }, idx) => (
<Td key={idx} size={size}>
{editing ? getField(name, input, inputProps) : view(value[name])}
<Tr error={!isEmpty(errors)} errorMessage={errors && errors.toString()}>
{elements.map(({ name, input, size, textAlign, view = identity, inputProps }, idx) => (
<Td key={idx} size={size} textAlign={textAlign}>
{editing ? getField(name, input, inputProps) : view(values[name])}
</Td>
))}
<Td size={175}>
@ -33,7 +39,7 @@ const ERow = ({ elements, cancel, save, value }) => {
<Link style={{ marginRight: '20px' }} color='secondary' onClick={innerCancel}>
Cancel
</Link>
<Link color='primary' onClick={save}>
<Link color='primary' onClick={innerSave}>
Save
</Link>
</>
@ -45,6 +51,21 @@ const ERow = ({ elements, cancel, save, value }) => {
</Td>
</Tr>
)
}
})
export default ERow
const ERowWithFormik = memo(({ value, validationSchema, save, elements }) => {
return (
<Formik
enableReinitialize
initialValues={value}
validationSchema={validationSchema}
onSubmit={save}
>
<Form>
<ERow elements={elements} />
</Form>
</Formik>
)
})
export default ERowWithFormik

View file

@ -1,4 +1,4 @@
import React from 'react'
import React, { memo } from 'react'
import { startCase } from 'lodash/fp'
import {
@ -10,23 +10,20 @@ import {
import ERow from './Row'
const ETable = ({ elements = [], data = [], cancel, save, components = {} }) => {
const { row } = components
const Row = row || ERow
const ETable = memo(({ elements = [], data = [], save, validationSchema }) => {
return (
<Table>
<THead>
{elements.map(({ name, size, header }, idx) => (
<Td header key={idx} size={size}>{header || startCase(name)}</Td>
{elements.map(({ name, size, header, textAlign }, idx) => (
<Td header key={idx} size={size} textAlign={textAlign}>{header || startCase(name)}</Td>
))}
<Td header size={175} />
</THead>
<TBody>
{data.map((it, idx) => <Row key={idx} value={it} elements={elements} cancel={cancel} save={save} />)}
{data.map((it, idx) => <ERow key={idx} value={it} elements={elements} save={save} validationSchema={validationSchema} />)}
</TBody>
</Table>
)
}
})
export default ETable

View file

@ -1,7 +1,7 @@
import React from 'react'
import classnames from 'classnames'
import ExpansionPanel from '@material-ui/core/ExpansionPanel'
import ExpansionPanelSummary from '@material-ui/core/ExpansionPanelSummary'
import Card from '@material-ui/core/Card'
import CardContent from '@material-ui/core/CardContent'
import { makeStyles } from '@material-ui/core/styles'
@ -10,20 +10,21 @@ import { Link } from '../../components/buttons'
import {
tableHeaderColor,
tableHeaderHeight,
tableErrorColor,
spacer,
white
} from '../../styling/variables'
import typographyStyles from '../typography/styles'
const { label2, p } = typographyStyles
const { tl2, p } = typographyStyles
const useStyles = makeStyles({
body: {
borderSpacing: '0 4px'
},
header: {
extend: label2,
extend: tl2,
backgroundColor: tableHeaderColor,
height: tableHeaderHeight,
textAlign: 'left',
@ -39,39 +40,31 @@ const useStyles = makeStyles({
display: 'table-cell',
padding: `0 ${spacer * 3}px`
},
summary: {
cursor: 'auto'
trError: {
backgroundColor: tableErrorColor
},
mainContent: {
display: 'flex',
alignItems: 'center',
minHeight: 54
},
// mui-overrides
panelRoot: {
cardContentRoot: {
// display: 'flex',
margin: 0,
padding: 0,
'&:last-child': {
padding: 0
}
},
card: {
extend: p,
display: 'table-row',
'&:before': {
height: 0
},
margin: '4px 0',
width: 'min-content',
boxShadow: '0 0 4px 0 rgba(0, 0, 0, 0.08)'
},
panelExpanded: {
'&:first-child': {
marginTop: '4px !important'
}
},
summaryRoot: {
userSelect: 'auto',
'&:hover:not(.Mui-disabled)': {
cursor: 'auto'
},
cursor: 'auto',
padding: 0
},
summaryContent: {
margin: 0,
height: 54,
alignItems: 'center'
},
summaryFocused: {
backgroundColor: 'inherit !important'
}
})
@ -99,7 +92,7 @@ const TBody = ({ children, className }) => {
)
}
const Td = ({ children, header, className, size = 100 }) => {
const Td = ({ children, header, className, size = 100, textAlign }) => {
const classes = useStyles()
const classNames = {
[classes.td]: true,
@ -107,23 +100,28 @@ const Td = ({ children, header, className, size = 100 }) => {
}
return (
<div className={classnames(className, classNames)} style={{ width: size }}>
<div className={classnames(className, classNames)} style={{ width: size, textAlign }}>
{children}
</div>
)
}
const Tr = ({ children }) => {
const Tr = ({ error, errorMessage, children }) => {
const classes = useStyles()
const epClasses = { root: classes.panelRoot, expanded: classes.panelExpanded }
const summaryClasses = { root: classes.summaryRoot, content: classes.summaryContent, focused: classes.summaryFocused }
const cardClasses = { root: classes.cardContentRoot }
const classNames = {
[classes.trError]: error
}
return (
<ExpansionPanel expanded={false} classes={epClasses} square>
<ExpansionPanelSummary tabIndex={null} classes={summaryClasses} className={classes.summary}>
{children}
</ExpansionPanelSummary>
</ExpansionPanel>
<>
<Card className={classnames(classNames, classes.card)}>
<CardContent classes={cardClasses}>
<div className={classes.mainContent}>{children}</div>
{error && <div className={classes.errorContent}>{errorMessage}</div>}
</CardContent>
</Card>
</>
)
}

View file

@ -35,13 +35,15 @@ const Autocomplete = memo(({ suggestions, classes, placeholder, label, itemToStr
}) => (
<div className={classes.container}>
{renderInput({
id: name,
fullWidth: true,
classes,
onBlur,
error: touched[name] && errors[name],
error: (touched[`${name}-input`] || touched[name]) && errors[name],
success: (touched[`${name}-input`] || touched[name] || value) && !errors[name],
InputProps: getInputProps({
value: inputValue2 || '',
placeholder,
onBlur,
onClick: () => toggleMenu(),
onChange: it => {
if (it.target.value === '') {

View file

@ -60,10 +60,11 @@ const AutocompleteMultiple = memo(
}) => (
<div className={classes.container}>
{renderInput({
id: name,
fullWidth: true,
classes,
onBlur,
error: touched[name] && errors[name],
error: (touched[`${name}-input`] || touched[name]) && errors[name],
success: (touched[`${name}-input`] || touched[name] || value) && !errors[name],
InputProps: getInputProps({
startAdornment: (value || []).map(item => (
<Chip
@ -72,6 +73,7 @@ const AutocompleteMultiple = memo(
label={item.code}
/>
)),
onBlur,
onChange: it => setInputValue(it.target.value),
onClick: () => toggleMenu(),
onKeyDown: handleKeyDown,

View file

@ -6,7 +6,7 @@ import MenuItem from '@material-ui/core/MenuItem'
import { fontColor, inputFontSize, inputFontWeight } from '../../../styling/variables'
function renderInput (inputProps) {
const { InputProps, classes, ref, ...other } = inputProps
const { onBlur, success, InputProps, classes, ref, ...other } = inputProps
return (
<TextField
@ -14,7 +14,8 @@ function renderInput (inputProps) {
inputRef: ref,
classes: {
root: classes.inputRoot,
input: classes.inputInput
input: classes.inputInput,
underline: success ? classes.success : ''
},
...InputProps
}}
@ -88,6 +89,11 @@ const styles = theme => ({
inputInput: {
flex: 1
},
success: {
'&:after': {
transform: 'scaleX(1)'
}
},
divider: {
height: theme.spacing(2)
}

View file

@ -25,22 +25,25 @@ function H4 ({ children, className, ...props }) {
return <h4 className={classnames(classes.h3, className)} {...props}>{children}</h4>
}
const P = pBuilder()
const P = pBuilder('p')
const Info1 = pBuilder('info1')
const Info2 = pBuilder('info2')
const Info3 = pBuilder('info3')
const Info4 = pBuilder('info4')
const Mono = pBuilder('mono')
const TL1 = pBuilder('tl1')
const TL2 = pBuilder('tl2')
const Label1 = pBuilder('label1')
const Label2 = pBuilder('label2')
const Label3 = pBuilder('label3')
function pBuilder (elementClass) {
return ({ inline, className, children, ...props }) => {
return ({ inline, noMargin, className, children, ...props }) => {
const classes = useStyles()
const classNames = {
[classes[elementClass]]: elementClass,
className: true,
[classes.inline]: inline
[classes.inline]: inline,
[classes.noMarginP]: noMargin
}
return (
<p className={classnames(classNames, className)} {...props}>
@ -50,4 +53,4 @@ function pBuilder (elementClass) {
}
}
export { H1, H2, H3, H4, TL1, TL2, P, Info1, Info2, Info3, Info4, Mono }
export { H1, H2, H3, H4, TL1, TL2, P, Info1, Info2, Info3, Mono, Label1, Label2, Label3 }

View file

@ -70,6 +70,12 @@ export default {
fontFamily: fontSecondary,
fontWeight: 700
},
info3: {
extend: base,
fontSize: fontSize3,
fontFamily: fontSecondary,
fontWeight: 500
},
mono: {
extend: base,
fontSize: fontSize4,
@ -95,7 +101,7 @@ export default {
fontWeight: 500,
lineHeight: '110%'
},
label: {
label1: {
fontSize: fontSize5,
fontFamily: fontSecondary,
fontWeight: 500
@ -105,6 +111,12 @@ export default {
fontFamily: fontSecondary,
fontWeight: 700
},
label3: {
fontSize: fontSize4,
fontFamily: fontSecondary,
fontWeight: 500,
color: fontColor
},
select: {
fontSize: fontSize3,
fontFamily: fontSecondary,
@ -112,5 +124,8 @@ export default {
},
inline: {
display: 'inline'
},
noMarginP: {
margin: 0
}
}

View file

@ -5,7 +5,7 @@ import BigNumber from 'bignumber.js'
import useAxios from '@use-hooks/axios'
import { makeStyles } from '@material-ui/core/styles'
import { H3, Info1, Info3, Info4, Mono } from '../components/typography'
import { H3, Info1, Info2, Info3, Mono, Label1, Label3, TL2 } from '../components/typography'
import Title from '../components/Title'
import Sidebar from '../components/Sidebar'
import { primaryColor } from '../styling/variables'
@ -58,6 +58,16 @@ const Funding = () => {
}
})
const itemRender = (it) => {
return (
<div className={classes.itemWrapper}>
<div className={classes.firstItem}>{it.display}</div>
<div className={classes.item}>{it.fiatConfirmedBalance} {it.fiatCode}</div>
<div className={classes.item}>{it.confirmedBalance} {it.cryptoCode}</div>
</div>
)
}
return (
<>
<Title>Funding</Title>
@ -67,14 +77,15 @@ const Funding = () => {
isSelected={isSelected}
onClick={setSelected}
displayName={it => it.display}
itemRender={itemRender}
>
{data && data.length && (
<div className={classes.total}>
<Info3 className={classes.totalTitle}>Total Crypto Balance</Info3>
<Label1 className={classes.totalTitle}>Total Crypto Balance</Label1>
<Info1 className={classes.noMargin}>
{getConfirmedTotal(data)} {data[0].fiatCode}
</Info1>
<Info4>(+{getPendingTotal(data)} pending)</Info4>
<Label1 className={classes.totalPending}>(+{getPendingTotal(data)} pending)</Label1>
</div>
)}
</Sidebar>
@ -83,21 +94,21 @@ const Funding = () => {
<div className={classes.firstSide}>
<H3>Balance ({selected.display})</H3>
<div className={classes.coinTotal}>
<span className='info1'>
<Info1 inline noMargin>
{`${selected.confirmedBalance} ${selected.cryptoCode}`}
</span>
<span className={classnames('tl2', classes.leftSpacer)}>
</Info1>
<Info2 inline noMargin className={classes.leftSpacer}>
{`(+ ${selected.pending} pending)`}
</span>
</Info2>
</div>
<div className={classes.coinTotal}>
<span className={classnames('info3', classes.noMarginTop)}>
<Info3 inline noMargin>
{`= ${formatNumber(selected.fiatConfirmedBalance)} ${selected.fiatCode}`}
</span>
<span className={classnames('info4', classes.leftSpacer)}>
</Info3>
<Label3 inline noMargin className={classes.leftSpacer}>
{`(+${formatNumber(selected.fiatPending)} pending)`}
</span>
</Label3>
</div>
<H3 className={classes.topSpacer}>Address</H3>
@ -109,7 +120,7 @@ const Funding = () => {
</div>
<div className={classes.secondSide}>
<Info3>Scan to send {selected.display}</Info3>
<Label1>Scan to send {selected.display}</Label1>
<QRCode size={240} fgColor={primaryColor} value={selected.fundingAddressUrl} />
</div>
</div>

View file

@ -1,4 +1,8 @@
import { spacer, subheaderColor, placeholderColor } from '../styling/variables'
import { spacer, subheaderColor, placeholderColor, fontColor } from '../styling/variables'
import typographyStyles from '../components/typography/styles'
const { label1 } = typographyStyles
export default {
wrapper: {
@ -38,12 +42,27 @@ export default {
width: 375,
margin: `${spacer * 1.5}px ${spacer * 3}px`
},
itemWrapper: {
textAlign: 'end'
},
item: {
extend: label1,
margin: 2
},
firstItem: {
margin: 2
},
total: {
marginTop: 'auto',
textAlign: 'right',
marginRight: 20
marginRight: 24
},
totalPending: {
color: fontColor,
marginTop: 2
},
totalTitle: {
color: placeholderColor
color: placeholderColor,
marginBottom: 2
}
}

View file

@ -1,5 +1,4 @@
import React, { memo, useState } from 'react'
import { withFormik } from 'formik'
import * as Yup from 'yup'
import useAxios from '@use-hooks/axios'
@ -24,7 +23,6 @@ const initialValues = {
const Locales = memo(() => {
const [locale, setLocale] = useState(initialValues)
const [editing, setEditing] = useState(false)
const [data, setData] = useState(null)
useAxios({
@ -48,21 +46,16 @@ const Locales = memo(() => {
}
})
const MainFormFormik = withFormik({
mapPropsToValues: () => locale,
validationSchema: LocaleSchema,
handleSubmit: it => {
setEditing(false)
const save = (it) => {
setLocale(it)
reFetch()
}
})(MainForm)
return (
<>
<Title>Locales</Title>
<Subtitle>Default settings</Subtitle>
<MainFormFormik editing={editing} setEditing={setEditing} data={data} />
<MainForm validationSchema={LocaleSchema} value={locale} save={save} auxData={data} />
<Subtitle extraMarginTop>Overrides</Subtitle>
</>
)

View file

@ -1,143 +1,32 @@
import React, { useState, memo } from 'react'
import { Form, FastField } from 'formik'
import { __, compose, join, map, get, isEmpty } from 'lodash/fp'
import React, { memo } from 'react'
import { __, compose, join, map, get } from 'lodash/fp'
import { Link } from '../../components/buttons'
import { Autocomplete, AutocompleteMultiple } from '../../components/inputs'
import { Checkbox } from '../../components/inputs/formik'
import {
EditCell,
Table,
TableHead,
TableRow,
TableHeader,
TableBody,
TableCell as Td
} from '../../components/table'
// import styles from './MainForm.module.scss'
import { Table as EditableTable } from '../../components/editableTable'
const styles = {}
const sizes = {
country: 200,
fiatCurrency: 150,
languages: 240,
cryptoCurrencies: 280,
cryptoCurrencies: 270,
showRates: 125,
action: 175
}
const MainForm = memo(
({ values, resetForm, submitForm, errors, editing, setEditing, data }) => {
const [submitted, setSubmitted] = useState(false)
const getData = get(__, data)
({ value, save, auxData, validationSchema }) => {
const getData = get(__, auxData)
const displayCodeArray = compose(join(', '), map(get('code')))
const save = () => {
setSubmitted(true)
submitForm()
}
const cancel = () => {
resetForm()
setSubmitted(false)
setEditing(false)
}
const ViewFields = (
<>
<Td>{values.country && values.country.display}</Td>
<Td>{values.fiatCurrency && values.fiatCurrency.code}</Td>
<Td>
{values.languages && values.languages.map(it => it.code).join(', ')}
</Td>
<Td>
{values.cryptoCurrencies &&
values.cryptoCurrencies.map(it => it.code).join(', ')}
</Td>
<Td>{values.showRates ? 'true' : 'false'}</Td>
<Td rightAlign>
<Link color='primary' onClick={() => setEditing(true)}>
Edit
</Link>
</Td>
</>
)
const EditFields = (
<>
<Td>
<FastField
name='country'
component={Autocomplete}
suggestions={data && data.countries}
/>
</Td>
<Td>
<FastField
name='fiatCurrency'
component={Autocomplete}
suggestions={data && data.currencies}
/>
</Td>
<Td>
<FastField
name='languages'
component={AutocompleteMultiple}
suggestions={data && data.languages}
/>
</Td>
<Td>
<FastField
name='cryptoCurrencies'
component={AutocompleteMultiple}
suggestions={data && data.cryptoCurrencies}
/>
</Td>
<Td>
<FastField name='showRates' component={Checkbox} />
</Td>
<EditCell save={save} cancel={cancel} />
</>
)
return (
<Form>
<Table>
<colgroup>
<col className={styles.bigColumn} />
<col className={styles.mediumColumn} />
<col className={styles.mediumColumn} />
<col className={styles.bigColumn} />
<col className={styles.showRates} />
<col className={styles.actionColumn} />
</colgroup>
<TableHead>
<TableRow header>
<TableHeader>Country</TableHeader>
<TableHeader>Fiat Currency</TableHeader>
<TableHeader>Languages</TableHeader>
<TableHeader>Crypto Currencies</TableHeader>
<TableHeader>Show Rates</TableHeader>
<TableHeader />
</TableRow>
</TableHead>
<TableBody>
<TableRow error={submitted && !isEmpty(errors)}>
{editing ? EditFields : ViewFields}
</TableRow>
</TableBody>
</Table>
<EditableTable
cancel={cancel}
save={save}
data={[values]}
validationSchema={validationSchema}
data={[value]}
elements={[
{
name: 'country',
@ -156,26 +45,26 @@ const MainForm = memo(
{
name: 'languages',
size: sizes.languages,
input: AutocompleteMultiple,
view: displayCodeArray,
input: AutocompleteMultiple,
inputProps: { suggestions: getData('languages') }
},
{
name: 'cryptoCurrencies',
size: sizes.languages,
input: AutocompleteMultiple,
size: sizes.cryptoCurrencies,
view: displayCodeArray,
input: AutocompleteMultiple,
inputProps: { suggestions: getData('cryptoCurrencies') }
},
{
name: 'showRates',
size: sizes.showRates,
input: Checkbox,
view: it => it ? 'true' : 'false'
textAlign: 'center',
view: it => it ? 'true' : 'false',
input: Checkbox
}
]}
/>
</Form>
)
}
)

View file

@ -1,4 +1,4 @@
const version = 8
const version = 9
// Primary
const zodiac = '#1b2559'
@ -8,8 +8,8 @@ const spring = '#48f694'
const comet = '#5f668a'
const comet2 = '#72799d'
const spring2 = '#44e188'
const spring4 = '#3fd07e'
const spring3 = '#ecfbef'
const spring4 = '#3fd07e'
const zircon = '#ebefff'
const zircon2 = '#dbdfed'
@ -75,7 +75,7 @@ if (version === 8) {
fontSize5 = 14
}
const smallestFontSize = fontSize5 - 1
const smallestFontSize = fontSize5
const inputFontSize = fontSize4
const inputFontSizeLg = fontSize1
const inputFontWeight = 500