Merge pull request #790 from josepfo/fix/clean-filters-button-styling

Fix: search filter section according to spec
This commit is contained in:
Rafael Taranto 2021-11-11 18:29:39 +00:00 committed by GitHub
commit 750bca63e5
9 changed files with 163 additions and 45 deletions

View file

@ -2,7 +2,7 @@ const db = require('../db')
const cashInTx = require('../cash-in/cash-in-tx') const cashInTx = require('../cash-in/cash-in-tx')
const { CASH_OUT_TRANSACTION_STATES } = require('../cash-out/cash-out-helper') const { CASH_OUT_TRANSACTION_STATES } = require('../cash-out/cash-out-helper')
function transaction() { function transaction () {
const sql = `SELECT DISTINCT * FROM ( const sql = `SELECT DISTINCT * FROM (
SELECT 'type' AS type, 'Cash In' AS value UNION SELECT 'type' AS type, 'Cash In' AS value UNION
SELECT 'type' AS type, 'Cash Out' AS value UNION SELECT 'type' AS type, 'Cash Out' AS value UNION
@ -27,7 +27,7 @@ function transaction() {
return db.any(sql) return db.any(sql)
} }
function customer() { function customer () {
const sql = `SELECT DISTINCT * FROM ( const sql = `SELECT DISTINCT * FROM (
SELECT 'phone' AS type, phone AS value FROM customers WHERE phone IS NOT NULL UNION SELECT 'phone' AS type, phone AS value FROM customers WHERE phone IS NOT NULL UNION
SELECT 'name' AS type, id_card_data::json->>'firstName' AS value FROM customers WHERE id_card_data::json->>'firstName' IS NOT NULL AND id_card_data::json->>'lastName' IS NULL UNION SELECT 'name' AS type, id_card_data::json->>'firstName' AS value FROM customers WHERE id_card_data::json->>'firstName' IS NOT NULL AND id_card_data::json->>'lastName' IS NULL UNION

View file

@ -1,7 +1,6 @@
const anonymous = require('../../../constants').anonymousCustomer const anonymous = require('../../../constants').anonymousCustomer
const customers = require('../../../customers') const customers = require('../../../customers')
const filters = require('../../filters') const filters = require('../../filters')
const loyalty = require('../../../loyalty')
const resolvers = { const resolvers = {
Customer: { Customer: {

View file

@ -2,37 +2,51 @@ import { makeStyles } from '@material-ui/core'
import React from 'react' import React from 'react'
import Chip from 'src/components/Chip' import Chip from 'src/components/Chip'
import { P } from 'src/components/typography' import { ActionButton } from 'src/components/buttons'
import { P, Label3 } from 'src/components/typography'
import { ReactComponent as CloseIcon } from 'src/styling/icons/action/close/zodiac.svg' import { ReactComponent as CloseIcon } from 'src/styling/icons/action/close/zodiac.svg'
import { ReactComponent as FilterIcon } from 'src/styling/icons/button/filter/white.svg'
import { ReactComponent as ReverseFilterIcon } from 'src/styling/icons/button/filter/zodiac.svg'
import { onlyFirstToUpper } from 'src/utils/string'
import { chipStyles, styles } from './SearchFilter.styles' import { chipStyles, styles } from './SearchFilter.styles'
const useChipStyles = makeStyles(chipStyles) const useChipStyles = makeStyles(chipStyles)
const useStyles = makeStyles(styles) const useStyles = makeStyles(styles)
const SearchFilter = ({ filters, onFilterDelete, setFilters }) => { const SearchFilter = ({ filters, onFilterDelete, setFilters, entries }) => {
const chipClasses = useChipStyles() const chipClasses = useChipStyles()
const classes = useStyles() const classes = useStyles()
return ( return (
<> <>
<P className={classes.text}>{'Filters:'}</P> <P className={classes.text}>{'Filters:'}</P>
<div> <div className={classes.filters}>
{filters.map((f, idx) => ( <div className={classes.chips}>
<Chip {filters.map((f, idx) => (
key={idx} <Chip
classes={chipClasses} key={idx}
label={`${f.type}: ${f.value}`} classes={chipClasses}
onDelete={() => onFilterDelete(f)} label={`${onlyFirstToUpper(f.type)}: ${f.value}`}
deleteIcon={<CloseIcon className={classes.button} />} onDelete={() => onFilterDelete(f)}
/> deleteIcon={<CloseIcon className={classes.button} />}
))} />
<Chip ))}
classes={chipClasses} </div>
label={`Delete filters`} <div className={classes.deleteWrapper}>
onDelete={() => setFilters([])} {
deleteIcon={<CloseIcon className={classes.button} />} <Label3 className={classes.entries}>{`${entries ??
/> 0} entries`}</Label3>
}
<ActionButton
color="secondary"
Icon={ReverseFilterIcon}
InverseIcon={FilterIcon}
className={classes.deleteButton}
onClick={() => setFilters([])}>
Delete filters
</ActionButton>
</div>
</div> </div>
</> </>
) )

View file

@ -4,28 +4,26 @@ import {
smallestFontSize, smallestFontSize,
inputFontFamily, inputFontFamily,
inputFontWeight, inputFontWeight,
spacer spacer,
offColor
} from 'src/styling/variables' } from 'src/styling/variables'
const chipStyles = { const chipStyles = {
root: { root: {
borderRadius: spacer / 2, marginLeft: 0,
marginTop: spacer / 2, height: 20,
marginRight: spacer / 4,
marginBottom: spacer / 2,
marginLeft: spacer / 4,
height: spacer * 3,
backgroundColor: zircon, backgroundColor: zircon,
'&:hover, &:focus, &:active': { '&:hover, &:focus, &:active': {
backgroundColor: zircon backgroundColor: zircon
} },
marginBottom: 'auto'
}, },
label: { label: {
fontSize: smallestFontSize, fontSize: smallestFontSize,
fontWeight: inputFontWeight, fontWeight: inputFontWeight,
fontFamily: inputFontFamily, fontFamily: inputFontFamily,
paddingRight: spacer / 2, paddingRight: 0,
paddingLeft: spacer / 2, paddingLeft: spacer,
color: primaryColor color: primaryColor
} }
} }
@ -34,11 +32,30 @@ const styles = {
button: { button: {
width: 8, width: 8,
height: 8, height: 8,
marginLeft: 8 marginLeft: 8,
marginRight: 8
}, },
text: { text: {
marginTop: 0, marginTop: 0,
marginBottom: 0 marginBottom: 0
},
filters: {
display: 'flex',
marginBottom: 16
},
deleteWrapper: {
display: 'flex',
marginLeft: 'auto',
justifyContent: 'flex-end',
flexDirection: 'row'
},
entries: {
color: offColor,
margin: 'auto',
marginRight: 12
},
chips: {
marginTop: 'auto'
} }
} }

View file

@ -20,36 +20,36 @@ const CustomersList = ({ data, locale, onClick, loading }) => {
const elements = [ const elements = [
{ {
header: 'Phone', header: 'Phone',
width: 172, width: 175,
view: it => getFormattedPhone(it.phone, locale.country) view: it => getFormattedPhone(it.phone, locale.country)
}, },
{ {
header: 'Name', header: 'Name',
width: 241, width: 247,
view: getName view: getName
}, },
{ {
header: 'Total TXs', header: 'Total TXs',
width: 126, width: 130,
textAlign: 'right', textAlign: 'right',
view: it => `${Number.parseInt(it.totalTxs)}` view: it => `${Number.parseInt(it.totalTxs)}`
}, },
{ {
header: 'Total spent', header: 'Total spent',
width: 152, width: 155,
textAlign: 'right', textAlign: 'right',
view: it => view: it =>
`${Number.parseFloat(it.totalSpent)} ${it.lastTxFiatCode ?? ''}` `${Number.parseFloat(it.totalSpent)} ${it.lastTxFiatCode ?? ''}`
}, },
{ {
header: 'Last active', header: 'Last active',
width: 133, width: 137,
view: it => view: it =>
ifNotNull(it.lastActive, moment.utc(it.lastActive).format('YYYY-MM-D')) ifNotNull(it.lastActive, moment.utc(it.lastActive).format('YYYY-MM-D'))
}, },
{ {
header: 'Last transaction', header: 'Last transaction',
width: 161, width: 165,
textAlign: 'right', textAlign: 'right',
view: it => { view: it => {
const hasLastTx = !R.isNil(it.lastTxFiatCode) const hasLastTx = !R.isNil(it.lastTxFiatCode)
@ -66,7 +66,7 @@ const CustomersList = ({ data, locale, onClick, loading }) => {
}, },
{ {
header: 'Status', header: 'Status',
width: 188, width: 191,
view: it => <MainStatus statuses={[getAuthorizedStatus(it)]} /> view: it => <MainStatus statuses={[getAuthorizedStatus(it)]} />
} }
] ]

View file

@ -286,18 +286,19 @@ const Transactions = () => {
)} )}
</div> </div>
<div className={classes.headerLabels}> <div className={classes.headerLabels}>
<div>
<TxOutIcon />
<span>Cash-out</span>
</div>
<div> <div>
<TxInIcon /> <TxInIcon />
<span>Cash-in</span> <span>Cash-in</span>
</div> </div>
<div>
<TxOutIcon />
<span>Cash-out</span>
</div>
</div> </div>
</div> </div>
{filters.length > 0 && ( {filters.length > 0 && (
<SearchFilter <SearchFilter
entries={filteredTransactions.length}
filters={filters} filters={filters}
onFilterDelete={onFilterDelete} onFilterDelete={onFilterDelete}
setFilters={setFilters} setFilters={setFilters}

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="12px" height="12px" viewBox="0 0 12 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>icon/button/filter/white</title>
<g id="icon/button/filter/white" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M0.6,-3.33066907e-16 L0.509218076,0.00652107669 C0.068925647,0.0708166555 -0.160361948,0.596737342 0.124968515,0.966531156 L4.166,6.204 L4.16660432,9.6 C4.16660432,9.79162756 4.25813682,9.97172829 4.41293455,10.0846831 L6.8797259,11.8846831 L6.96095139,11.9350192 C7.34801849,12.1353088 7.83339568,11.8580867 7.83339568,11.4 L7.833,6.204 L11.8750315,0.966531156 C12.179384,0.572084421 11.8982155,-3.33066907e-16 11.4,-3.33066907e-16 L0.6,-3.33066907e-16 Z M10.179,1.199 L6.75836419,5.63346884 L6.70465653,5.71638775 C6.65811535,5.80315577 6.63339568,5.90052663 6.63339568,6 L6.633,10.219 L5.366,9.294 L5.36660432,6 L5.35847177,5.90154229 C5.34231401,5.80441508 5.30240262,5.71222382 5.24163581,5.63346884 L1.82,1.199 L10.179,1.199 Z" id="Path" fill="#FFFFFF" fill-rule="nonzero"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="12px" height="12px" viewBox="0 0 12 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>icon/button/filter/zodiac</title>
<g id="icon/button/filter/zodiac" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M0.6,-4.56301663e-14 L0.509218076,0.00652107669 C0.068925647,0.0708166555 -0.160361948,0.596737342 0.124968515,0.966531156 L4.166,6.204 L4.16660432,9.6 C4.16660432,9.79162756 4.25813682,9.97172829 4.41293455,10.0846831 L6.8797259,11.8846831 L6.96095139,11.9350192 C7.34801849,12.1353088 7.83339568,11.8580867 7.83339568,11.4 L7.833,6.204 L11.8750315,0.966531156 C12.179384,0.572084421 11.8982155,-4.56301663e-14 11.4,-4.56301663e-14 L0.6,-4.56301663e-14 Z M10.179,1.199 L6.75836419,5.63346884 L6.70465653,5.71638775 C6.65811535,5.80315577 6.63339568,5.90052663 6.63339568,6 L6.633,10.219 L5.366,9.294 L5.36660432,6 L5.35847177,5.90154229 C5.34231401,5.80441508 5.30240262,5.71222382 5.24163581,5.63346884 L1.82,1.199 L10.179,1.199 Z" id="Path" fill="#1B2559" fill-rule="nonzero"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

77
package-lock.json generated
View file

@ -17319,6 +17319,13 @@
"integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
"requires": { "requires": {
"ms": "2.1.2" "ms": "2.1.2"
},
"dependencies": {
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}
} }
}, },
"http-proxy-agent": { "http-proxy-agent": {
@ -17332,9 +17339,14 @@
} }
}, },
"ms": { "ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
},
"yallist": {
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
} }
} }
}, },
@ -19680,6 +19692,11 @@
"locate-path": "^2.0.0" "locate-path": "^2.0.0"
} }
}, },
"ignore": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
"integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg=="
},
"load-json-file": { "load-json-file": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
@ -19702,6 +19719,11 @@
"path-exists": "^3.0.0" "path-exists": "^3.0.0"
} }
}, },
"ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
},
"p-limit": { "p-limit": {
"version": "1.3.0", "version": "1.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
@ -19741,6 +19763,16 @@
"find-up": "^2.0.0", "find-up": "^2.0.0",
"load-json-file": "^4.0.0" "load-json-file": "^4.0.0"
} }
},
"progress": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="
},
"regexpp": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz",
"integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw=="
} }
} }
}, },
@ -20184,6 +20216,11 @@
"universalify": "^0.1.0" "universalify": "^0.1.0"
} }
}, },
"is-buffer": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz",
"integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ=="
},
"jsonfile": { "jsonfile": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
@ -20476,6 +20513,29 @@
"xtend": "~4.0.1" "xtend": "~4.0.1"
}, },
"dependencies": { "dependencies": {
"debug": {
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
"requires": {
"ms": "^2.1.1"
}
},
"form-data": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz",
"integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==",
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.6",
"mime-types": "^2.1.12"
}
},
"ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
},
"readable-stream": { "readable-stream": {
"version": "2.3.7", "version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
@ -20571,6 +20631,14 @@
"kind-of": "^3.0.2" "kind-of": "^3.0.2"
}, },
"dependencies": { "dependencies": {
"debug": {
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
"requires": {
"ms": "^2.1.1"
}
},
"kind-of": { "kind-of": {
"version": "3.2.2", "version": "3.2.2",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
@ -20579,6 +20647,11 @@
"requires": { "requires": {
"is-buffer": "^1.1.5" "is-buffer": "^1.1.5"
} }
},
"ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
} }
} }
}, },