Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: page agnostic features #37

Merged
merged 12 commits into from
Jun 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions frontend/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,8 @@
"@typescript-eslint/consistent-type-imports": "off",
"@typescript-eslint/strict-boolean-expressions": "off",
"@typescript-eslint/indent": "off"
}
}
},
"ignorePatterns": [
"src/scripts/*.js"
]
}
8 changes: 7 additions & 1 deletion frontend/public/handlebars_template.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,10 @@
<body>
<div id="root"></div>
<script src="{% static '{{ reactUrl }}' %}"></script>
</body>
</body>

<!-- OneTrust Cookies Consent Notice -->
<script type="text/javascript"
src="https://cdn-ukwest.onetrust.com/consent/5da42396-cb12-4493-8d04-5179033cfbad/OtAutoBlock.js"></script>
<script src="https://cdn-ukwest.onetrust.com/scripttemplates/otSDKStub.js" type="text/javascript" charset="UTF-8"
data-domain-script="5da42396-cb12-4493-8d04-5179033cfbad"></script>
8 changes: 7 additions & 1 deletion frontend/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,10 @@
<script src="../src/index.tsx"></script>
</body>

</html>
</html>

<!-- OneTrust Cookies Consent Notice -->
<script type="text/javascript"
src="https://cdn-ukwest.onetrust.com/consent/5da42396-cb12-4493-8d04-5179033cfbad/OtAutoBlock.js"></script>
<script src="https://cdn-ukwest.onetrust.com/scripttemplates/otSDKStub.js" type="text/javascript" charset="UTF-8"
data-domain-script="5da42396-cb12-4493-8d04-5179033cfbad"></script>
25 changes: 16 additions & 9 deletions frontend/src/app/App.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
import React from 'react';
import React, { useEffect } from 'react';
import { Provider } from 'react-redux';
import CssBaseline from '@mui/material/CssBaseline';
import { ThemeProvider } from '@mui/material/styles';

import store from './store';
import theme from './theme';
import { HideContactUsWidget } from '../features/thirdParty';

const App: React.FC<{
children: React.ReactNode
}> = ({ children }) => (
<ThemeProvider theme={theme}>
<CssBaseline />
<Provider store={store}>
{children}
</Provider>
</ThemeProvider>
);
}> = ({ children }) => {
useEffect(() => {
HideContactUsWidget();
}, []);

return (
<ThemeProvider theme={theme}>
<CssBaseline />
<Provider store={store}>
{children}
</Provider>
</ThemeProvider>
);
};

export default App;
8 changes: 8 additions & 0 deletions frontend/src/app/interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export { };

declare global {
interface Window {
FreshworksWidget: any;
Optanon: any;
}
}
44 changes: 44 additions & 0 deletions frontend/src/features/MessageBanner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React, { useState } from 'react';
import {
Unstable_Grid2 as Grid,
Typography,
Breakpoint,
Stack,
Container,
useTheme
} from '@mui/material';
import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined';
import ErrorOutlineOutlinedIcon from '@mui/icons-material/ErrorOutlineOutlined';
import CloseIcon from '@mui/icons-material/Close';

const MessageBanner: React.FC = () => {
const theme = useTheme();
const messageTag = 'info';
const message = 'message';
const [showBanner, setShowBanner] = useState(false);

const handleClose = (): void => {
setShowBanner(false);
};

return (
showBanner
? <Grid container xs={12} style={{ backgroundColor: theme.palette.tertiary.main }} alignItems='center'>
<Container maxWidth={process.env.REACT_APP_CONTAINER_MAX_WIDTH as Breakpoint}>
<Stack direction='row' alignItems='center'>
{(messageTag.includes('error') || messageTag.includes('warning'))
? <ErrorOutlineOutlinedIcon />
: <InfoOutlinedIcon />
}
<Typography marginX={2} marginY={2} sx={{ flexGrow: 1 }}>
{message}
</Typography>
<CloseIcon onClick={handleClose} />
</Stack>
</Container>
</Grid>
: null
);
};

export default MessageBanner;
41 changes: 41 additions & 0 deletions frontend/src/features/ScreenTimePopUp.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from 'react';
import {
Stack,
Button,
Dialog,
Typography
} from '@mui/material';
import { Image } from 'codeforlife/lib/esm/components';
import BrainImage from '../images/brain.svg';

const ScreenTimePopUp: React.FC<{
open: boolean,
setOpen: React.Dispatch<React.SetStateAction<boolean>>,
}> = ({ open, setOpen }) => {
const handleClose = (): void => {
setOpen(false);
};

return (
<Dialog
open={open}
onClose={handleClose}
maxWidth='sm'
>
<Stack alignItems='center' margin={3}>
<Image src={BrainImage} alt={'brain'} maxWidth={100} marginY={3} />
<Typography variant='h5' textAlign='center'>
Time for a break?
</Typography>
<Typography textAlign='center'>
You have been using the Code for Life website for a while. Remember to take regular screen breaks to recharge those brain cells!
</Typography>
<Button onClick={handleClose} autoFocus>
Continue
</Button>
</Stack>
</Dialog>
);
};

export default ScreenTimePopUp;
45 changes: 45 additions & 0 deletions frontend/src/features/SessionPopUp.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React from 'react';
import {
Stack,
Button,
Dialog,
Typography
} from '@mui/material';
import Timer from './Timer';

const SessionPopUp: React.FC<{
open: boolean,
setOpen: React.Dispatch<React.SetStateAction<boolean>>,
}> = ({ open, setOpen }) => {
const handleClose = (): void => {
setOpen(false);
// TODO: close the popup after 2 mins and call the logout endpoint
};

return (
<Dialog
open={open}
onClose={handleClose}
maxWidth='sm'
>
<Stack alignItems='center' margin={3}>
<Typography variant='h5' textAlign='center'>
Where did you go? 👀
</Typography>
<Typography textAlign='center'>
We noticed that you have been inactive for a while. Are you still there? For your
online safety we will log you out in:
</Typography>
<Timer delaySecond={120} />
<Typography textAlign='center'>
You may lose progress unless you continue or save.
</Typography>
<Button onClick={handleClose} autoFocus>
Wait, I&apos;m still here!
</Button>
</Stack>
</Dialog>
);
};

export default SessionPopUp;
31 changes: 31 additions & 0 deletions frontend/src/features/Timer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Typography } from '@mui/material';
import React, { useEffect, useState } from 'react';

const Timer: React.FC<{
delaySecond: number,
}> = ({ delaySecond }) => {
const [delay, setDelay] = useState(+delaySecond);
const minutes = Math.floor(delay / 60);
const seconds = Math.floor(delay % 60);
useEffect(() => {
const timer = setInterval(() => {
setDelay(delay - 1);
}, 1000);

if (delay === 0) {
clearInterval(timer);
}

return () => {
clearInterval(timer);
};
});

return (
<Typography variant='h5' textAlign='center'>
{minutes} min {seconds} secs
</Typography>
);
};

export default Timer;
5 changes: 3 additions & 2 deletions frontend/src/features/footer/Links.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
} from '@mui/material';

import { paths } from '../../app/router';
import { OpenContactUsWidget, ShowCookiesDrawer } from '../thirdParty';

const Links: React.FC = () => (
<ThemeProvider theme={createTheme(useTheme(), {
Expand All @@ -26,7 +27,7 @@ const Links: React.FC = () => (
<Link href={paths.aboutUs._}>
About us
</Link>
<Link>
<Link onClick={OpenContactUsWidget}>
Help and support
</Link>
</Stack>
Expand All @@ -39,7 +40,7 @@ const Links: React.FC = () => (
<Link href={paths.termsOfUse._}>
Terms of use
</Link>
<Link>
<Link onClick={ShowCookiesDrawer}>
Cookie settings
</Link>
</Stack>
Expand Down
11 changes: 11 additions & 0 deletions frontend/src/features/thirdParty.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export const OpenContactUsWidget = (): void => {
window.FreshworksWidget('open');
};

export const HideContactUsWidget = (): void => {
window.FreshworksWidget('hide');
};

export const ShowCookiesDrawer = (): void => {
window.Optanon.ToggleInfoDisplay();
};
1 change: 1 addition & 0 deletions frontend/src/images/brain.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions frontend/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import App from './app/App';
import router from './app/router';
import reportWebVitals from './reportWebVitals';

import './scripts/freshDesk';

const container = document.getElementById('root');

if (container === null) throw new Error('root element is null');
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/pages/aboutUs/Supporters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import MCSaatchiImage from '../../images/mc_saatchi_logo.png';
import HOPEImage from '../../images/hope_logo.png';
import GLAImage from '../../images/gla_logo.png';
import PressureCookerImage from '../../images/pressure_cooker_logo.png';
import { OpenContactUsWidget } from '../../features/thirdParty';

const ImageGrid: React.FC<{
alt: string,
Expand Down Expand Up @@ -74,7 +75,7 @@ const Supporters: React.FC = () => {
Teachers, parents, and creatives
</Typography>
<Typography>
Please get in touch through our <Link color="inherit" underline="always">contact</Link> form and let us know how you would like to get involved.
Please get in touch through our <Link onClick={OpenContactUsWidget} className='body'>contact</Link> form and let us know how you would like to get involved.
</Typography>
<Typography>
We would like to thank our friends who have contributed to this initiative.
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/pages/privacyNotice/ForAdults/Cookies.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
Link,
Button
} from '@mui/material';
import { ShowCookiesDrawer } from '../../../features/thirdParty';

const CustomTableRow: React.FC<{
withoutUnderline?: boolean,
Expand Down Expand Up @@ -139,8 +140,7 @@ const Cookies: React.FC = () => (
<Typography>
You can change your cookie preferences or withdraw consent by clicking on the following button:
</Typography>
{/* TODO: set cookie settings button */}
<Button href=''>
<Button onClick={ShowCookiesDrawer}>
Cookie Settings
</Button>
</>
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/pages/privacyNotice/ForChildren/Cookies.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
Link,
Button
} from '@mui/material';
import { ShowCookiesDrawer } from '../../../features/thirdParty';

const CustomTableRow: React.FC<{
withoutUnderline?: boolean,
Expand Down Expand Up @@ -131,9 +132,8 @@ const Cookies: React.FC = () => <>
<Typography>
You can switch the functional and analytics cookies on and off at any time by clicking this button below.
</Typography>
{/* TODO: open cookie settings on click */}
{/* TODO: set padding bottom via theme */}
<Button>
<Button onClick={ShowCookiesDrawer}>
Cookie Settings
</Button>
<Typography>
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/pages/termsOfUse/ForAdults/Alerting.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import {
Link,
Typography
} from '@mui/material';
import { OpenContactUsWidget } from '../../../features/thirdParty';

const Alerting: React.FC = () => {
// TODO: setup contact us link.
return (
<Stack>
<Typography>
If you see anything on the Code for Life portal which appears to infringe any part of the Terms & Conditions, then please inform us via the <Link href='' color='inherit' underline='always'>Contact Us</Link> section of this site.
If you see anything on the Code for Life portal which appears to infringe any part of the Terms & Conditions, then please inform us via the <Link onClick={OpenContactUsWidget} className='body'>Contact Us</Link> section of this site.
</Typography>
<Typography>
We do not endorse or take responsibility for the content of any third party sites that link to or from Code for Life.
Expand Down
6 changes: 4 additions & 2 deletions frontend/src/pages/termsOfUse/ForAdults/Misuse.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import React from 'react';
import {
Stack,
ListItemText,
Typography
Typography,
Link
} from '@mui/material';

import { ItemizedList } from 'codeforlife/lib/esm/components';
import { OpenContactUsWidget } from '../../../features/thirdParty';

const Misuse: React.FC = () => {
return (
Expand All @@ -17,7 +19,7 @@ const Misuse: React.FC = () => {
Any person whose access has been suspended or terminated may not re-register for, or re-access, the Code for Life portal without our prior written consent. You are responsible for everything which is done on or through the Code for Life portal through your registered email address(es) or whilst your Users account is logged on to the Code for Life site. In addition, we reserve the right to suspend or terminate any User’s access to Code for Life, or parts of it, if the relevant User is abusive, discriminatory or threatening, or harasses or communicates offensive messages or images to another User; irrespective of whether this is done through the Code for Life site.
</Typography>
<Typography>
We endeavour to ensure that the Code for Life website and access to your account and our games, platforms and other products or services are available 24 hours a day, but occasionally your access to the Code for Life website or to your account (including any old or live games or avatars) may be restricted to allow for repairs, maintenance or the introduction of new features or services. We aim to provide the best service possible, but we do not warrant that the Code for Life website, access to your account or any of the games, platforms or any of our other products or services (whether online or otherwise) will be fault, virus or error free. If you detect a problem or fault, please contact us using the contact us form and we will endeavour to correct the fault as quickly as we can.
We endeavour to ensure that the Code for Life website and access to your account and our games, platforms and other products or services are available 24 hours a day, but occasionally your access to the Code for Life website or to your account (including any old or live games or avatars) may be restricted to allow for repairs, maintenance or the introduction of new features or services. We aim to provide the best service possible, but we do not warrant that the Code for Life website, access to your account or any of the games, platforms or any of our other products or services (whether online or otherwise) will be fault, virus or error free. If you detect a problem or fault, please contact us using the <Link onClick={OpenContactUsWidget} className='body'>contact us form</Link> and we will endeavour to correct the fault as quickly as we can.
</Typography>
<Typography>
Notwithstanding any of the above, we reserve the right to decline any new registrations or suspend or cancel a User’s account at any time and at our sole discretion (and without telling you beforehand), and we reserve the right to terminate your access to all or part of the games, platforms and other products or services that we make available from time to time (whether online or otherwise) which shall include any old or live games or avatar(s) you have created.
Expand Down
Loading