(Feature) Implement GDPR requirements (#490)

* (fix) format script command

* (add) "Accept preferences" link

* (add) footer

* (fix) mobile accept preferences link

* (fix) linting

* (fix) script typo
This commit is contained in:
Gabriel Rodríguez Alsina 2020-01-31 11:06:22 -03:00 committed by GitHub
parent ef79515972
commit 84926fde82
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 130 additions and 84 deletions

View File

@ -23,7 +23,7 @@
"start": "node scripts/start.js",
"start-mainnet": "REACT_APP_NETWORK=mainnet yarn start",
"test": "NODE_ENV=test && node scripts/test.js --env=jsdom",
"format": "prettier-eslint \"src/**/*.js\" --write"
"format": "prettier-eslint $PWD'/src/**/*.{js,jsx}' --write"
},
"pre-commit": [
"precommit"
@ -152,4 +152,4 @@
"webpack-dev-server": "3.9.0",
"webpack-manifest-plugin": "2.2.0"
}
}
}

View File

@ -1,14 +1,15 @@
// @flow
import Checkbox from '@material-ui/core/Checkbox'
import Close from '@material-ui/icons/Close'
import FormControlLabel from '@material-ui/core/FormControlLabel'
import IconButton from '@material-ui/core/IconButton'
import React, { useEffect, useState } from 'react'
import { makeStyles } from '@material-ui/core/styles'
import { useDispatch, useSelector } from 'react-redux'
import cn from 'classnames'
import Link from '~/components/layout/Link'
import Button from '~/components/layout/Button'
import { primary, mainFontFamily, md } from '~/theme/variables'
import {
primary, mainFontFamily, md, screenSm,
} from '~/theme/variables'
import type { CookiesProps } from '~/logic/cookies/model/cookie'
import { COOKIES_KEY } from '~/logic/cookies/model/cookie'
import { loadFromCookie, saveCookie } from '~/logic/cookies/utils'
@ -48,9 +49,12 @@ const useStyles = makeStyles({
columnGap: '10px',
display: 'grid',
gridTemplateColumns: '1fr',
paddingBottom: '30px',
rowGap: '10px',
'@media (min-width: 960px)': {
[`@media (min-width: ${screenSm}px)`]: {
gridTemplateColumns: '1fr 1fr 1fr',
paddingBottom: '0',
},
},
formItem: {
@ -64,10 +68,20 @@ const useStyles = makeStyles({
textDecoration: 'none',
},
},
close: {
acceptPreferences: {
bottom: '-20px',
cursor: 'pointer',
position: 'absolute',
right: '12px',
top: '12px',
right: '20px',
textDecoration: 'underline',
[`@media (min-width: ${screenSm}px)`]: {
bottom: '-10px',
},
'&:hover': {
textDecoration: 'none',
},
},
})
@ -120,12 +134,16 @@ const CookiesBanner = () => {
const cookieBannerContent = (
<div className={classes.container}>
<IconButton onClick={() => closeCookiesBannerHandler()} className={classes.close}><Close /></IconButton>
<span role="button" tabIndex="0" onClick={closeCookiesBannerHandler} onKeyDown={closeCookiesBannerHandler} className={cn(classes.acceptPreferences, classes.text)}>
Accept preferences &gt;
</span>
<div className={classes.content}>
<p className={classes.text}>
We use cookies to give you the best experience and to help improve our website. Please read our
{' '}
<Link className={classes.link} to="https://safe.gnosis.io/cookie">Cookie Policy</Link>
<Link className={classes.link} to="https://safe.gnosis.io/cookie">
Cookie Policy
</Link>
{' '}
for more information. By clicking &quot;Accept all&quot;, you agree to the storing of cookies on your device
to enhance site navigation, analyze site usage and provide customer support.
@ -139,9 +157,7 @@ const CookiesBanner = () => {
name="Necessary"
onChange={() => setLocalNecessary((prev) => !prev)}
value={localNecessary}
control={(
<Checkbox disabled />
)}
control={<Checkbox disabled />}
/>
</div>
<div className={classes.formItem}>
@ -150,9 +166,7 @@ const CookiesBanner = () => {
name="Analytics"
onChange={() => setLocalAnalytics((prev) => !prev)}
value={localAnalytics}
control={(
<Checkbox checked={localAnalytics} />
)}
control={<Checkbox checked={localAnalytics} />}
/>
</div>
<div className={classes.formItem}>

View File

@ -0,0 +1,95 @@
// @flow
import * as React from 'react'
import { makeStyles } from '@material-ui/core/styles'
import { useDispatch } from 'react-redux'
import cn from 'classnames'
import Link from '~/components/layout/Link'
import { secondary, screenSm, sm } from '~/theme/variables'
import { openCookieBanner } from '~/logic/cookies/store/actions/openCookieBanner'
import GnoButtonLink from '~/components/layout/ButtonLink'
const useStyles = makeStyles({
footer: {
display: 'flex',
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'center',
margin: '0 auto',
maxWidth: '100%',
padding: `40px ${sm} 20px`,
width: `${screenSm}px`,
},
item: {
color: 'rgba(0, 0, 0, 0.54)',
fontSize: '13px',
},
link: {
color: secondary,
textDecoration: 'none',
'&:hover': {
textDecoration: 'underline',
},
},
sep: {
color: 'rgba(0, 0, 0, 0.54)',
margin: '0 10px',
},
buttonLink: {
padding: '0',
},
})
const appVersion = process.env.REACT_APP_APP_VERSION ? `v${process.env.REACT_APP_APP_VERSION} ` : 'Versions'
const Footer = () => {
const date = new Date()
const classes = useStyles()
const dispatch = useDispatch()
const openCookiesHandler = () => {
dispatch(openCookieBanner(true))
}
return (
<footer className={classes.footer}>
<span className={classes.item}>
©
{' '}
{date.getFullYear()}
{' '}
Gnosis
</span>
<span className={classes.sep}>|</span>
<Link className={cn(classes.item, classes.link)} to="https://safe.gnosis.io/terms" target="_blank">
Terms
</Link>
<span className={classes.sep}>|</span>
<Link className={cn(classes.item, classes.link)} to="https://safe.gnosis.io/privacy" target="_blank">
Privacy
</Link>
<span className={classes.sep}>|</span>
<Link className={cn(classes.item, classes.link)} to="https://safe.gnosis.io/licenses" target="_blank">
Licenses
</Link>
<span className={classes.sep}>|</span>
<Link className={cn(classes.item, classes.link)} to="https://safe.gnosis.io/imprint" target="_blank">
Imprint
</Link>
<span className={classes.sep}>|</span>
<Link className={cn(classes.item, classes.link)} to="https://safe.gnosis.io/cookie" target="_blank">
Cookie Policy
</Link>
<span className={classes.sep}>-</span>
<GnoButtonLink className={cn(classes.item, classes.link, classes.buttonLink)} onClick={openCookiesHandler}>
Preferences
</GnoButtonLink>
<span className={classes.sep}>|</span>
<Link className={cn(classes.item, classes.link)} to="https://github.com/gnosis/safe-react/releases" target="_blank">
{appVersion}
</Link>
</footer>
)
}
export default Footer

View File

@ -1,63 +0,0 @@
// @flow
import React from 'react'
import { makeStyles } from '@material-ui/core/styles'
import { useDispatch } from 'react-redux'
import Block from '~/components/layout/Block'
import Link from '~/components/layout/Link'
import { sm, primary } from '~/theme/variables'
import { openCookieBanner } from '~/logic/cookies/store/actions/openCookieBanner'
import GnoButtonLink from '~/components/layout/ButtonLink'
const useStyles = makeStyles({
container: {
padding: `${sm} 0`,
},
link: {
color: primary,
},
buttonLink: {
textDecoration: 'none',
color: primary,
},
})
type Props = {
toggleSidebar: Function,
}
const appVersion = process.env.REACT_APP_APP_VERSION ? `v${process.env.REACT_APP_APP_VERSION}` : 'Versions'
const LegalLinks = (props: Props) => {
const classes = useStyles()
const dispatch = useDispatch()
const openCookiesHandler = () => {
dispatch(openCookieBanner(true))
props.toggleSidebar()
}
return (
<Block className={classes.container} justify="space-around">
<Link className={classes.link} to="https://safe.gnosis.io/terms" target="_blank">
Terms
</Link>
<Link className={classes.link} to="https://safe.gnosis.io/privacy" target="_blank">
Privacy
</Link>
<Link className={classes.link} to="https://safe.gnosis.io/licenses" target="_blank">
Licenses
</Link>
<Link className={classes.link} to="https://safe.gnosis.io/imprint" target="_blank">
Imprint
</Link>
<GnoButtonLink className={classes.buttonLink} onClick={openCookiesHandler}>
Cookies
</GnoButtonLink>
<Link className={classes.link} to="https://github.com/gnosis/safe-react/releases" target="_blank">
{appVersion}
</Link>
</Block>
)
}
export default LegalLinks

View File

@ -21,7 +21,6 @@ import {
import setDefaultSafe from '~/routes/safe/store/actions/setDefaultSafe'
import { sortedSafeListSelector } from './selectors'
import SafeList from './SafeList'
import LegalLinks from './LegalLinks'
import useSidebarStyles from './style'
const { useState, useEffect, useMemo } = React
@ -46,8 +45,8 @@ type SidebarProps = {
const filterBy = (filter: string, safes: List<Safe>): List<Safe> => safes.filter(
(safe: Safe) => !filter
|| safe.address.toLowerCase().includes(filter.toLowerCase())
|| safe.name.toLowerCase().includes(filter.toLowerCase()),
|| safe.address.toLowerCase().includes(filter.toLowerCase())
|| safe.name.toLowerCase().includes(filter.toLowerCase()),
)
const Sidebar = ({
@ -137,7 +136,6 @@ const Sidebar = ({
defaultSafe={defaultSafe}
currentSafe={currentSafe}
/>
<LegalLinks toggleSidebar={toggleSidebar} />
</Drawer>
</ClickAwayListener>
{children}

View File

@ -6,6 +6,7 @@ import { withStyles } from '@material-ui/core/styles'
import Backdrop from '~/components/layout/Backdrop'
import CookiesBanner from '~/components/CookiesBanner'
import Header from '~/components/Header'
import Footer from '~/components/Footer'
import Img from '~/components/layout/Img'
import Notifier from '~/components/Notifier'
import SidebarProvider from '~/components/Sidebar'
@ -67,6 +68,7 @@ const PageFrame = ({ children, classes, currentNetwork }: Props) => {
<SidebarProvider>
<Header />
{children}
<Footer />
</SidebarProvider>
</SnackbarProvider>
<CookiesBanner />