Skip to content

Commit 47017c1

Browse files
authored
Merge pull request #1127 from civictechindex/Hover_Cookie_Box
Cookie_Hover_Box
2 parents c7a16c4 + 4f54f78 commit 47017c1

File tree

7 files changed

+270
-44
lines changed

7 files changed

+270
-44
lines changed
Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,53 @@
1-
const faker = require('faker')
1+
const faker = require('faker');
22

33
describe('Footer', () => {
4-
const BAD_FORMAT_EMAIL = 'test@'
5-
const DUPLICATE_EMAIL = 'test@test.test'
4+
const BAD_FORMAT_EMAIL = 'test@';
5+
const DUPLICATE_EMAIL = 'test@test.test';
66
const RANDOM_EMAIL = `test_${faker.internet.email()}`;
77

88
before(() => {
9-
cy.visit('/home')
10-
})
9+
cy.visit('/home');
10+
});
1111

1212
it('footer loads', () => {
1313
cy.get('[class*=containerFooter]').within(() => {
14-
cy.contains('The Civic Tech Index is an open-source project, read more on our')
15-
})
16-
})
14+
cy.contains(
15+
'The Civic Tech Index is an open-source project, read more on our'
16+
);
17+
});
18+
});
1719

1820
it('navigates to donate', () => {
1921
cy.get('[class*=containerFooter]').within(() => {
20-
cy.contains('Collaborate with Us').click()
21-
cy.get('[href*=donate]').click()
22-
})
23-
cy.get('[class*=makeStyles-infoThank]')
24-
.contains('We appreciate your contribution.')
25-
})
22+
cy.contains('Collaborate with Us').click();
23+
cy.get('[href*=donate]').click();
24+
});
25+
cy.get('[class*=makeStyles-infoThank]').contains(
26+
'We appreciate your contribution.'
27+
);
28+
});
2629

2730
it('does not capture a poorly formatted email address', () => {
2831
cy.get('[class*=containerFooter]').within(() => {
29-
cy.get('input').clear().type(BAD_FORMAT_EMAIL)
30-
cy.get('button').click()
31-
cy.contains('The email address you have submitted was invalid.')
32-
})
33-
})
32+
cy.get('input').clear().type(BAD_FORMAT_EMAIL);
33+
cy.get('button').click({ force: true });
34+
cy.contains('The email address you have submitted was invalid.');
35+
});
36+
});
3437

3538
it('does not capture a registered email address', () => {
3639
cy.get('[class*=containerFooter]').within(() => {
37-
cy.get('input').clear().type(DUPLICATE_EMAIL)
38-
cy.get('button').click()
39-
cy.contains('That email address has already been registered with us.')
40-
})
41-
})
40+
cy.get('input').clear().type(DUPLICATE_EMAIL);
41+
cy.get('button').click();
42+
cy.contains('That email address has already been registered with us.');
43+
});
44+
});
4245

4346
it('captures a new email address', () => {
4447
cy.get('[class*=containerFooter]').within(() => {
45-
cy.get('input').clear().type(RANDOM_EMAIL)
46-
cy.get('button').click()
47-
cy.contains('Thanks for subscribing!')
48-
})
49-
})
50-
})
48+
cy.get('input').clear().type(RANDOM_EMAIL);
49+
cy.get('button').click();
50+
cy.contains('Thanks for subscribing!');
51+
});
52+
});
53+
});
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
describe('Privacy Popup', () => {
2+
before(() => {
3+
cy.visit('/home')
4+
});
5+
6+
it('verifies cookie notice is visible', () => {
7+
cy.get('[id*=cookieNotice]')
8+
.should(
9+
'contain',
10+
'Cookies and Privacy Policy'
11+
)
12+
.should(
13+
'contain',
14+
'We use cookies and other tracking technologies'
15+
).within(() => {
16+
cy.get('[data-cy=accept-cookie]').should('be.visible');
17+
cy.get('[data-cy=privacy-link]').should('be.visible');
18+
});
19+
});
20+
21+
it('navigates to privacy page', () => {
22+
cy.get('[data-cy=privacy-link]').click();
23+
cy.contains('Privacy Policy');
24+
});
25+
26+
it('loads home page and shows hover box', () => {
27+
cy.visit('/home');
28+
cy.get('[id*=cookieNotice]').should('be.visible');
29+
});
30+
31+
it('closes cookie notice', () => {
32+
cy.get('[data-cy=accept-cookie]').click();
33+
cy.get('[id*=cookieNotice]').should('not.be.visible');
34+
});
35+
});

cypress/integration/pages/privacy.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
describe('About Page', () => {
1+
describe('Privacy Policy Page', () => {
22
before(() => {
33
cy.visit('/privacy')
44
})

public/images/cookie.png

901 Bytes
Loading

src/App.js

Lines changed: 66 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import React, { useEffect } from 'react';
1+
/* eslint-disable max-lines-per-function */
2+
import React, { useEffect, useState } from 'react';
23
import { BrowserRouter, Redirect, Route, Switch } from 'react-router-dom';
34
import { QueryParamProvider } from 'use-query-params';
45
import Layout from './components/common/Layout';
@@ -17,44 +18,96 @@ import SearchProjects from './pages/SearchProjects';
1718
import TagGenerator from './pages/TagGenerator';
1819
import Error404 from './pages/Error404';
1920
import ShareTheCti from './pages/Share';
20-
import Privacy from './pages/Privacy'
21+
import Privacy from './pages/Privacy';
22+
import PopUp from './pages/Privacy/PopUp';
2123
import Guides from './guides/';
2224
import useStyles from './styles';
2325

2426
const RouteTitled = ({ title, ...rest }) => {
2527
useEffect(() => {
2628
if (title) {
27-
document.title = `Civic Tech Index — ${title}`
29+
document.title = `Civic Tech Index — ${title}`;
2830
}
2931
});
3032

3133
return <Route {...rest} />;
3234
};
3335

3436
const App = () => {
37+
const [showModal, setShowModal] = useState(false);
3538
useStyles();
3639
return (
3740
<BrowserRouter>
3841
<ScrollToTop />
42+
<PopUp showModal={showModal} setShowModal={setShowModal} />
3943
<QueryParamProvider ReactRouterRoute={Route}>
4044
<Layout>
4145
<Switch>
4246
<Route exact path='/' component={Landing} />
4347
<RouteTitled exact path='/about' component={About} title='About' />
44-
<RouteTitled exact path='/about/contact' component={Contact} title='Contact Us' />
48+
<RouteTitled
49+
exact
50+
path='/about/contact'
51+
component={Contact}
52+
title='Contact Us'
53+
/>
4554
<RouteTitled exact path='/about/faq' component={Faq} title='FAQ' />
46-
<RouteTitled exact path={'/organizations'} component={Contributors} title='Organizations' />
55+
<RouteTitled
56+
exact
57+
path={'/organizations'}
58+
component={Contributors}
59+
title='Organizations'
60+
/>
4761
<RouteTitled exact path='/home' component={Home} title='Home' />
48-
<RouteTitled exact path='/projects' component={SearchProjects} title='Search Projects' />
49-
<RouteTitled exact path='/join-index' component={TagGenerator} title='Join the Index' />
50-
<RouteTitled exact path='/join-index/how-to-add' component={HowToAdd} title='How to Add Your Project' />
51-
<RouteTitled exact path='/support/collaborate' component={Collaborate} title='Collaborate with Us' />
52-
<RouteTitled exact path='/support/donate' component={Donate} title='Donate' />
53-
<RouteTitled exact path='/support/share' component={ShareTheCti} title='Share the CTI' />
54-
<RouteTitled exact path='/privacy' component={Privacy} title='Privacy' />
62+
<RouteTitled
63+
exact
64+
path='/projects'
65+
component={SearchProjects}
66+
title='Search Projects'
67+
/>
68+
<RouteTitled
69+
exact
70+
path='/join-index'
71+
component={TagGenerator}
72+
title='Join the Index'
73+
/>
74+
<RouteTitled
75+
exact
76+
path='/join-index/how-to-add'
77+
component={HowToAdd}
78+
title='How to Add Your Project'
79+
/>
80+
<RouteTitled
81+
exact
82+
path='/support/collaborate'
83+
component={Collaborate}
84+
title='Collaborate with Us'
85+
/>
86+
<RouteTitled
87+
exact
88+
path='/support/donate'
89+
component={Donate}
90+
title='Donate'
91+
/>
92+
<RouteTitled
93+
exact
94+
path='/support/share'
95+
component={ShareTheCti}
96+
title='Share the CTI'
97+
/>
98+
<RouteTitled
99+
exact
100+
path='/privacy'
101+
component={Privacy}
102+
title='Privacy'
103+
/>
55104
<Route exact path='/organization/:name' component={IndvOrgPage} />
56105
{/* test and error page routes begin */}
57-
<RouteTitled path='/guides/:guide' component={Guides} title='Guides' />
106+
<RouteTitled
107+
path='/guides/:guide'
108+
component={Guides}
109+
title='Guides'
110+
/>
58111
<RouteTitled path='/404' component={Error404} title='404' />
59112
{/* test and error page routes end */}
60113
<Redirect from='/add' to='/join-index/how-to-add' />

src/components/Header/NavLink.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ const NavLink = ({ label, id, children, header, route, title }) => {
6363
anchorOrigin={{ horizontal: 'left', vertical: 'bottom' }}
6464
transformOrigin={{ horizontal: 'left', vertical: 'top' }}
6565
PopoverClasses={{ paper: classes.popover }}
66+
disableScrollLock={true}
6667
{...bindMenu(popupState)}
6768
>
6869
<div>{children}</div>

src/pages/Privacy/PopUp.js

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
import React from 'react';
2+
import { makeStyles } from '@material-ui/core/styles';
3+
import Link from '../../components/common/Link';
4+
import Button from '@material-ui/core/Button';
5+
import Card from '@material-ui/core/Card';
6+
import CardActions from '@material-ui/core/CardActions';
7+
import CardContent from '@material-ui/core/CardContent';
8+
import { CardHeader } from '@material-ui/core';
9+
import Typography from '@material-ui/core/Typography';
10+
11+
const useStyles = makeStyles((theme) => ({
12+
root: {
13+
width: '360px',
14+
height: '206px',
15+
zIndex: 50000,
16+
position: 'fixed',
17+
right: '2px',
18+
bottom: '2px',
19+
},
20+
title: {
21+
fontSize: '20px',
22+
fontWeight: '700',
23+
},
24+
headStyle: {
25+
padding: 8,
26+
},
27+
iconStyle: {
28+
verticalAlign: 'bottom',
29+
},
30+
copyStyle: {
31+
paddingTop: 5,
32+
width: '308px',
33+
},
34+
hoverContent: {
35+
fontSize: 12,
36+
textAlign: 'justify',
37+
lineHeight: '16.2px',
38+
},
39+
linkStyle: {
40+
padding: 0,
41+
color: '#FFB100',
42+
marginLeft: 3,
43+
textDecoration: 'none',
44+
},
45+
imageStyle: {
46+
width: '26px',
47+
height: '26px',
48+
marginRight: '2%',
49+
verticalAlign: 'middle',
50+
},
51+
buttonLinkStyle: {
52+
justifyContent: 'flex-end',
53+
},
54+
buttonStyle: {
55+
width: '150px',
56+
height: '36px',
57+
color: '#0F1D2F',
58+
fontWeight: '700',
59+
},
60+
linkText: {
61+
color: '#0F1D2F',
62+
fontWeight: '700',
63+
paddingRight: '25px',
64+
},
65+
}));
66+
67+
const PopUp = () => {
68+
const classes = useStyles();
69+
const date = new Date();
70+
const setCookie = function (cookieEmail) {
71+
let cookieValue, expDays;
72+
date.setTime(date.getTime() + expDays);
73+
const expires = 'expires=' + date.toUTCString();
74+
75+
document.cookie = `${cookieEmail}${cookieValue}';'${expires}';path=/'`;
76+
77+
return document.cookie;
78+
};
79+
80+
const deleteCookie = function (cookieEmail) {
81+
date.setTime(date.getTime());
82+
const expires = 'expires=' + date.toUTCString();
83+
document.cookie = `${cookieEmail}${expires}';path=/'`;
84+
};
85+
const acceptCookieConsent = () => {
86+
deleteCookie('civictechindex_cookie_consent');
87+
setCookie('civictechindex_cookie_consent', 1, 30);
88+
document.getElementById('cookieNotice').style.display = 'none';
89+
};
90+
91+
return (
92+
<Card className={classes.root} id='cookieNotice'>
93+
<CardHeader className={classes.headStyle}></CardHeader>
94+
<Typography className={classes.title}>
95+
<img
96+
src='/images/cookie.png'
97+
alt='Cookie logo'
98+
className={classes.imageStyle}
99+
/>
100+
<span>Cookies and Privacy Policy </span>
101+
</Typography>
102+
<CardContent className={classes.copyStyle}>
103+
<Typography
104+
className={classes.hoverContent}
105+
data-cy='cookie-privacy-textdescription'
106+
>
107+
We use cookies and other tracking technologies to improve your
108+
browsing experience and to better understand our website traffic. By
109+
browsing our website, you consent to our use of cookies and other
110+
tracking technologies.
111+
</Typography>
112+
<CardActions className={classes.buttonLinkStyle}>
113+
<Link
114+
className={classes.linkText}
115+
data-cy='privacy-link'
116+
key='privacy'
117+
to='/privacy'
118+
>
119+
LEARN MORE{' '}
120+
</Link>
121+
<Button
122+
className={classes.buttonStyle}
123+
data-cy='accept-cookie'
124+
onClick={acceptCookieConsent}
125+
>
126+
Accept
127+
</Button>
128+
</CardActions>
129+
</CardContent>
130+
</Card>
131+
);
132+
};
133+
134+
export default PopUp;

0 commit comments

Comments
 (0)