Skip to content

Commit

Permalink
Refactor footer into separate files
Browse files Browse the repository at this point in the history
  • Loading branch information
camille-s committed Aug 27, 2024
1 parent 9591e91 commit 863f209
Show file tree
Hide file tree
Showing 6 changed files with 206 additions and 179 deletions.
94 changes: 94 additions & 0 deletions src/components/Layout/Footer/Dictionary/Dictionary.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import PropTypes from 'prop-types';
import Typography from '@mui/material/Typography';
import Accordion from '@mui/material/Accordion';
import AccordionSummary from '@mui/material/AccordionSummary';
import AccordionDetails from '@mui/material/AccordionDetails';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import Link from '@mui/material/Link';
import FooterRow from '../FooterRow/FooterRow';

const Dictionary = ({ definitions, format, }) => (
<FooterRow heading='Definitions of terms'>
{definitions.map((section, i) => (
<DictionarySection key={`def-section-${i}`}
format={format}
{...section}
i={i}
/>
))}
</FooterRow>
);

Dictionary.propTypes = {
definitions: PropTypes.arrayOf(PropTypes.object).isRequired,
format: PropTypes.func,
};

const DictionarySection = ({ source, format, variables, i, }) => (
<Accordion
disableGutters
elevation={0}
>
<AccordionSummary
aria-controls={`def-section-content-${i}`}
id={`def-section-header-${i}`}
expandIcon={<ExpandMoreIcon />}
sx={{
'& .MuiAccordionSummary-content': {
margin: '4px 0',
},
}}
size='small'
variant='filled'
>
<Typography variant='h4'>{source}</Typography>
</AccordionSummary>
<AccordionDetails
sx={{
'& dl': {
margin: 0,
}
}}
>
<dl>
{variables.map((def, j) => (
<Definition format={format} key={`def-${j}`} {...def} />
))}
</dl>
</AccordionDetails>
</Accordion>
);

DictionarySection.propTypes = {
source: PropTypes.string.isRequired,
variables: PropTypes.arrayOf(PropTypes.object).isRequired,
i: PropTypes.number.isRequired,
format: PropTypes.func,
};

const Definition = ({ term, definition, url, format }) => (
<>
<dt
style={{
fontWeight: '600',
}}
>
{term}
</dt>
<dd>
{format(definition)}
{url && (
<Link href={url}> Learn more here.</Link>
)}
</dd>
</>
);

Definition.propTypes = {
term: PropTypes.string.isRequired,
definition: PropTypes.string,
url: PropTypes.string,
format: PropTypes.func,
};

export default Dictionary;
28 changes: 28 additions & 0 deletions src/components/Layout/Footer/Download/Download.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import PropTypes from 'prop-types';
import Typography from '@mui/material/Typography';
import Link from '@mui/material/Link';
import FooterRow from '../FooterRow/FooterRow';

const Download = ({ dwBase, dwSlug, ghBase, csvFn }) => {
const dlLink = <Link href={`https://query.data.world/s/${dwSlug}`}>Download</Link>;
const dwLink = <Link href={dwBase}>data.world</Link>;
const ghLink = <Link href={`${ghBase}/${csvFn}`}>GitHub</Link>;
return (
<FooterRow heading='Download data'>
<Typography>
{dlLink} data for all towns and COGs (.csv file),
filter and analyze data online on {dwLink} (requires free sign-up),
or download / clone from {ghLink} (advanced users).
</Typography>
</FooterRow>
);
};

Download.propTypes = {
dwBase: PropTypes.string.isRequired,
dwSlug: PropTypes.string.isRequired,
ghBase: PropTypes.string.isRequired,
csvFn: PropTypes.string.isRequired,
};

export default Download;
186 changes: 7 additions & 179 deletions src/components/Layout/Footer/Footer.jsx
Original file line number Diff line number Diff line change
@@ -1,186 +1,12 @@
import PropTypes from 'prop-types';
import Panel from '../Panel/Panel';
import Typography from '@mui/material/Typography';
import Link from '@mui/material/Link';
import Box from '@mui/material/Box';
import Stack from '@mui/material/Stack';
import Divider from '@mui/material/Divider';
import Accordion from '@mui/material/Accordion';
import AccordionSummary from '@mui/material/AccordionSummary';
import AccordionDetails from '@mui/material/AccordionDetails';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import Download from './Download/Download';
import Geography from './Geography/Geography';
import Sources from './Sources/Sources';
import Dictionary from './Dictionary/Dictionary';

/*****************
* // FOOTER ROW *
*****************/
const FooterRow = ({ heading, children }) => (
<Box>
<Typography
variant='h3'
gutterBottom
>{heading}</Typography>
{children}
</Box>
);

FooterRow.propTypes = {
heading: PropTypes.string.isRequired,
children: PropTypes.node.isRequired,
};

/***************
* // DOWNLOAD *
***************/
const Download = ({ dwBase, dwSlug, ghBase, csvFn }) => {
const dlLink = <Link href={`https://query.data.world/s/${dwSlug}`}>Download</Link>;
const dwLink = <Link href={dwBase}>data.world</Link>;
const ghLink = <Link href={`${ghBase}/${csvFn}`}>GitHub</Link>;
return (
<FooterRow heading='Download data'>
<Typography>
{dlLink} data for all towns and COGs (.csv file),
filter and analyze data online on {dwLink} (requires free sign-up),
or download / clone from {ghLink} (advanced users).
</Typography>
</FooterRow>
);
};

Download.propTypes = {
dwBase: PropTypes.string.isRequired,
dwSlug: PropTypes.string.isRequired,
ghBase: PropTypes.string.isRequired,
csvFn: PropTypes.string.isRequired,
};

/****************
* // GEOGRAPHY *
****************/
const Geography = ({ towns, cog }) => (
<FooterRow heading='Geography'>
<Typography>
Note that in order to include Community Wellbeing Survey results for small towns, values shown here are based on a model that incorporates direct measurements. Contact DataHaven for more information about the methodology used.
</Typography>
{towns && <Typography>
{`${cog} is made up of the towns of ${towns}.`}
</Typography>}
</FooterRow>
);

Geography.propTypes = {
towns: PropTypes.string,
cog: PropTypes.string,
};

/**************
* // SOURCES *
**************/
const Sources = ({ sources }) => (
<FooterRow heading='Source: DataHaven analysis (2024) of:'>
<ul style={{ margin: 0 }}>
{sources.map((source, i) => (
<Source key={i} {...source} />
))}
</ul>
</FooterRow>
);

Sources.propTypes = {
sources: PropTypes.arrayOf(PropTypes.object).isRequired,
};

const Source = ({ project, source, url, year }) => (
<li>
<span style={{
fontWeight: '600',
}}>{`${source} `}</span>
{`(${year}). `}
<Link href={url}>{`${project}`}</Link>
</li>
);

Source.propTypes = {
project: PropTypes.string.isRequired,
source: PropTypes.string.isRequired,
url: PropTypes.string.isRequired,
year: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
};

/*****************
* // DICTIONARY *
*****************/
const Dictionary = ({ definitions, }) => (
<FooterRow heading='Definitions of terms'>
{definitions.map((section, i) => (
<DictionarySection key={i} {...section} i={i} />
))}
</FooterRow>
);

Dictionary.propTypes = {
definitions: PropTypes.arrayOf(PropTypes.object).isRequired,
};

const DictionarySection = ({ source, variables, i, }) => (
<Accordion
disableGutters
elevation={0}
>
<AccordionSummary
aria-controls={`def-section-content-${i}`}
id={`def-section-header-${i}`}
expandIcon={<ExpandMoreIcon />}
sx={{
'& .MuiAccordionSummary-content': {
margin: '4px 0',
},
}}
size='small'
variant='filled'
>
<Typography variant='h4'>{source}</Typography>
</AccordionSummary>
<AccordionDetails
sx={{
'& dl': {
margin: 0,
}
}}
>
<dl>
{variables.map((def, j) => (
<Definition key={`def-${j}`} {...def} />
))}
</dl>
</AccordionDetails>
</Accordion>
);

DictionarySection.propTypes = {
source: PropTypes.string.isRequired,
variables: PropTypes.arrayOf(PropTypes.object).isRequired,
i: PropTypes.number.isRequired,
};

const Definition = ({ indicator, detail }) => (
<>
<dt
style={{
fontWeight: '600',
}}
>{indicator}</dt>
<dd>{detail}</dd>
</>
);

Definition.propTypes = {
indicator: PropTypes.string.isRequired,
detail: PropTypes.string,
};

/*************
* // FOOTER *
*************/
const Footer = ({
dwBase,
ghBase,
Expand All @@ -190,6 +16,7 @@ const Footer = ({
cog,
sources,
dictionary,
format,
}) => (
<Panel heading={`Notes`}>
<Stack
Expand All @@ -214,7 +41,7 @@ const Footer = ({

<Sources sources={sources} />

<Dictionary definitions={dictionary} />
<Dictionary definitions={dictionary} format={format} />
</Stack>
</Panel>
);
Expand All @@ -228,6 +55,7 @@ Footer.propTypes = {
cog: PropTypes.string,
sources: PropTypes.arrayOf(PropTypes.object).isRequired,
dictionary: PropTypes.arrayOf(PropTypes.object).isRequired,
format: PropTypes.func,
};

export default Footer;
20 changes: 20 additions & 0 deletions src/components/Layout/Footer/FooterRow/FooterRow.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import PropTypes from 'prop-types';
import Typography from '@mui/material/Typography';
import Box from '@mui/material/Box';

const FooterRow = ({ heading, children }) => (
<Box>
<Typography
variant='h3'
gutterBottom
>{heading}</Typography>
{children}
</Box>
);

FooterRow.propTypes = {
heading: PropTypes.string.isRequired,
children: PropTypes.node.isRequired,
};

export default FooterRow;
21 changes: 21 additions & 0 deletions src/components/Layout/Footer/Geography/Geography.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import PropTypes from 'prop-types';
import Typography from '@mui/material/Typography';
import FooterRow from '../FooterRow/FooterRow';

const Geography = ({ towns, cog }) => (
<FooterRow heading='Geography'>
<Typography>
Note that in order to include Community Wellbeing Survey results for small towns, values shown here are based on a model that incorporates direct measurements. Contact DataHaven for more information about the methodology used.
</Typography>
{towns && <Typography>
{`${cog} is made up of the towns of ${towns}.`}
</Typography>}
</FooterRow>
);

Geography.propTypes = {
towns: PropTypes.string,
cog: PropTypes.string,
};

export default Geography;
Loading

0 comments on commit 863f209

Please sign in to comment.