mirror of
https://github.com/DOI-DO/j40-cejst-2.git
synced 2025-07-31 20:31:16 -07:00
About page sprint4 (#544)
* Card sections of the About page * Create index.test.tsx * Add test that verifies no console errors and no undefined variables. * Added unit test with snapshot * use global.console.error * Fix unit test for console.error() * Remove areasOfFocusList since it's no longer used * CSS adjustments from PR * Add back in AlertWrapper * github.com link opens in new tab * adds comment to globalize console.error check * Refactor AboutCard * Fixing the top grid so it resizes correctly on mobile. (e.g. using `<Grid desktop={{col: 9}}>` will expand to full width when going to mobile. * So AboutCard can now do 'large' cards (ones at the top) and 'small' cards (ones at the bottom that are 2x per row). * change `desktop` -> `tablet` * `<Grid col={1}>{' '}</Grid>` Co-authored-by: Vim <86254807+vim-usds@users.noreply.github.com>
This commit is contained in:
parent
f7bfc979ba
commit
a2eabda319
11 changed files with 448 additions and 266 deletions
22
client/src/components/AboutCard/AboutCard.test.tsx
Normal file
22
client/src/components/AboutCard/AboutCard.test.tsx
Normal file
|
@ -0,0 +1,22 @@
|
|||
import * as React from 'react';
|
||||
import {render} from '@testing-library/react';
|
||||
import {LocalizedComponent} from '../../test/testHelpers';
|
||||
import AboutCard from './AboutCard';
|
||||
|
||||
describe('rendering of the AboutCard', () => {
|
||||
const {asFragment} = render(
|
||||
<LocalizedComponent>
|
||||
<AboutCard
|
||||
imgSrc={'about:blank'}
|
||||
header={'Test Header'}
|
||||
actionText={'Test Action'}
|
||||
actionUrl={'#'}>
|
||||
Content body of the action card.
|
||||
</AboutCard>
|
||||
</LocalizedComponent>,
|
||||
);
|
||||
|
||||
it('checks if component renders', () => {
|
||||
expect(asFragment()).toMatchSnapshot();
|
||||
});
|
||||
});
|
77
client/src/components/AboutCard/AboutCard.tsx
Normal file
77
client/src/components/AboutCard/AboutCard.tsx
Normal file
|
@ -0,0 +1,77 @@
|
|||
import React from 'react';
|
||||
import {Grid} from '@trussworks/react-uswds';
|
||||
|
||||
// the "body" section is the child object to allow for html versus just text
|
||||
interface AboutCardProps {
|
||||
imgSrc: string;
|
||||
header: string;
|
||||
size?: 'small' | 'large';
|
||||
actionText?: string;
|
||||
actionUrl?: string;
|
||||
actionOpenInNewTab?: boolean;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const AboutCard = (props: React.PropsWithChildren<AboutCardProps>) => {
|
||||
if (props.size === 'large') {
|
||||
// large are the cards on top
|
||||
// note it uses a top className='j40-aboutcard-lg-card'
|
||||
return (
|
||||
<Grid tablet={{col: true}} gap={'lg'} className={(props.className || '')}>
|
||||
<Grid row className={'j40-aboutcard-lg-card'}>
|
||||
<Grid tablet={{col: 3}} className={'j40-aboutpage-image-container'}>
|
||||
<img
|
||||
className={'j40-aboutcard-image'}
|
||||
alt={props.header}
|
||||
src={props.imgSrc}/>
|
||||
</Grid>
|
||||
|
||||
<Grid tablet={{col: 9}}>
|
||||
<Grid row>
|
||||
<h3 className={'j40-section-header'}>{props.header}</h3>
|
||||
<div className={'j40-section-body'}>{props.children}</div>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
} else {
|
||||
// small are the cards on the bottom
|
||||
// note it uses a top className='j40-aboutcard-sm-card'
|
||||
return (
|
||||
<Grid tablet={{col: true}} gap={'lg'} className={(props.className || '')}>
|
||||
<Grid row className={'j40-aboutcard-sm-card'}>
|
||||
<Grid tablet={{col: 2}} className={'j40-aboutpage-image-container'}>
|
||||
<img
|
||||
className={'j40-aboutcard-image'}
|
||||
alt={props.header}
|
||||
src={props.imgSrc}/>
|
||||
</Grid>
|
||||
|
||||
<Grid tablet={{col: 9}}>
|
||||
<Grid row>
|
||||
<h3 className={'j40-section-header'}>{props.header}</h3>
|
||||
<div className={'j40-section-body'}>{props.children}</div>
|
||||
<div className={'j40-section-footer'}>
|
||||
{props.actionOpenInNewTab ?
|
||||
<a
|
||||
className={'j40-aboutcard-link'}
|
||||
href={props.actionUrl}
|
||||
target="_blank"
|
||||
rel="noreferrer">{props.actionText}</a> :
|
||||
<a
|
||||
className={'j40-aboutcard-link'}
|
||||
href={props.actionUrl}>{props.actionText}</a>
|
||||
}
|
||||
</div>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid col={1}>{' '}</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default AboutCard;
|
17
client/src/components/AboutCard/AboutCardsContainer.tsx
Normal file
17
client/src/components/AboutCard/AboutCardsContainer.tsx
Normal file
|
@ -0,0 +1,17 @@
|
|||
import React from 'react';
|
||||
import {Grid} from '@trussworks/react-uswds';
|
||||
|
||||
type AboutCardsContainerProps = {
|
||||
className?: string
|
||||
}
|
||||
|
||||
// note: this assumes a J40MainGridContainer container!
|
||||
const AboutCardsContainer = (props: React.PropsWithChildren<AboutCardsContainerProps>) => {
|
||||
return (
|
||||
<Grid row gap={'lg'} className={'j40-aboutcard-container ' + (props.className || '')}>
|
||||
{props.children}
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
export default AboutCardsContainer;
|
|
@ -0,0 +1,56 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`rendering of the AboutCard checks if component renders 1`] = `
|
||||
<DocumentFragment>
|
||||
<div
|
||||
class="grid-gap-lg tablet:grid-col"
|
||||
data-testid="grid"
|
||||
>
|
||||
<div
|
||||
class="grid-row j40-aboutcard-card"
|
||||
data-testid="grid"
|
||||
>
|
||||
<div
|
||||
class="grid-col-2"
|
||||
data-testid="grid"
|
||||
>
|
||||
<img
|
||||
alt="Test Header"
|
||||
class="j40-aboutcard-image"
|
||||
src="about:blank"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="grid-col-10"
|
||||
data-testid="grid"
|
||||
>
|
||||
<div
|
||||
class="grid-row"
|
||||
data-testid="grid"
|
||||
>
|
||||
<div
|
||||
class="j40-section-header"
|
||||
>
|
||||
Test Header
|
||||
</div>
|
||||
<div
|
||||
class="j40-section-body"
|
||||
>
|
||||
Content body of the action card.
|
||||
</div>
|
||||
<div
|
||||
class="j40-section-footer"
|
||||
>
|
||||
<a
|
||||
class="j40-aboutcard-link"
|
||||
href="#"
|
||||
>
|
||||
Test Action
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DocumentFragment>
|
||||
`;
|
|
@ -6,13 +6,18 @@ import {GridContainer} from '@trussworks/react-uswds';
|
|||
interface ILayoutProps {
|
||||
children: ReactNode,
|
||||
fullWidth?: boolean,
|
||||
blueBackground?: boolean,
|
||||
className?: string
|
||||
}
|
||||
|
||||
const J40MainGridContainer = ({
|
||||
children,
|
||||
fullWidth = false,
|
||||
className = 'j40-grid-container'}: ILayoutProps) => {
|
||||
blueBackground = false,
|
||||
className = 'j40-grid-container '}: ILayoutProps) => {
|
||||
// is it a blue background strip?
|
||||
className += (blueBackground ? 'j40-main-grid-blue-bk ' : '');
|
||||
|
||||
return fullWidth ? (
|
||||
<div
|
||||
className={'j40-grid-container ' + className}>
|
||||
|
|
|
@ -1,97 +0,0 @@
|
|||
import * as React from 'react';
|
||||
// import * as styles from './areasOfFocusList.module.scss'; // TODO: move styles
|
||||
import {useIntl} from 'gatsby-plugin-intl';
|
||||
import {defineMessages} from 'react-intl';
|
||||
|
||||
|
||||
// this section seems too verbose? must be a more readable way to do this.
|
||||
// this inlines the svg as data:image/svg+xml For larger images this
|
||||
// can cause page bloat, but it should be fine here.
|
||||
// @ts-ignore
|
||||
import ecoIcon from '/node_modules/uswds/dist/img/usa-icons/eco.svg';
|
||||
// @ts-ignore
|
||||
import busIcon from '/node_modules/uswds/dist/img/usa-icons/directions_bus.svg';
|
||||
// @ts-ignore
|
||||
import homeIcon from '/node_modules/uswds/dist/img/usa-icons/home.svg';
|
||||
// @ts-ignore
|
||||
import groupsIcon from '/node_modules/uswds/dist/img/usa-icons/groups.svg';
|
||||
import pollutionIcon // @ts-ignore
|
||||
from '/node_modules/uswds/dist/img/usa-icons/severe_weather.svg';
|
||||
// @ts-ignore
|
||||
import washIcon from '/node_modules/uswds/dist/img/usa-icons/wash.svg';
|
||||
// @ts-ignore
|
||||
import publicIcon from '/node_modules/uswds/dist/img/usa-icons/public.svg';
|
||||
|
||||
const AreasOfFocusList = () => {
|
||||
const intl = useIntl();
|
||||
const messages = defineMessages({
|
||||
climate: {
|
||||
id: 'areasOfInterest.climate',
|
||||
defaultMessage: 'Climate change',
|
||||
description: 'item in areasOfInterest list',
|
||||
},
|
||||
energy: {
|
||||
id: 'areasOfInterest.energy',
|
||||
defaultMessage: 'Clean energy and energy efficiency',
|
||||
description: 'item in areasOfInterest list',
|
||||
},
|
||||
transit: {
|
||||
id: 'areasOfInterest.transit',
|
||||
defaultMessage: 'Clean transit',
|
||||
description: 'item in areasOfInterest list',
|
||||
},
|
||||
housing: {
|
||||
id: 'areasOfInterest.housing',
|
||||
defaultMessage: 'Affordable and sustainable housing',
|
||||
description: 'item in areasOfInterest list',
|
||||
},
|
||||
training: {
|
||||
id: 'areasOfInterest.training',
|
||||
defaultMessage: 'Training and workforce development',
|
||||
description: 'item in areasOfInterest list',
|
||||
},
|
||||
pollution: {
|
||||
id: 'areasOfInterest.pollution',
|
||||
defaultMessage: 'Remediation of legacy pollution',
|
||||
description: 'item in areasOfInterest list',
|
||||
},
|
||||
water: {
|
||||
id: 'areasOfInterest.water',
|
||||
defaultMessage: 'Clean water infrastructure',
|
||||
description: 'item in areasOfInterest list',
|
||||
},
|
||||
});
|
||||
|
||||
const readMoreList: (any | string)[][] = [
|
||||
[publicIcon, intl.formatMessage(messages.climate)],
|
||||
[ecoIcon, intl.formatMessage(messages.energy)],
|
||||
[busIcon, intl.formatMessage(messages.transit)],
|
||||
[homeIcon, intl.formatMessage(messages.housing)],
|
||||
[groupsIcon, intl.formatMessage(messages.training)],
|
||||
[pollutionIcon, intl.formatMessage(messages.pollution)],
|
||||
[washIcon, intl.formatMessage(messages.water)],
|
||||
];
|
||||
return (
|
||||
<div className={'j40-two-column-confine'}>
|
||||
<ul className={'j40-two-column'}>
|
||||
{readMoreList.map((item, index) => {
|
||||
return (
|
||||
<li key={`readmore_li_${index}`}>
|
||||
<div className={'usa-icon-list__icon'}>
|
||||
<img
|
||||
className={'j40-two-column-icons-spacing'}
|
||||
key={`readmore_img_${index}`}
|
||||
src={item[0]} alt={item[1] + ' icon'}/>
|
||||
</div>
|
||||
<div
|
||||
className={'usa-icon-list__content'}> {item[1]} </div>
|
||||
</li>
|
||||
);
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AreasOfFocusList;
|
Loading…
Add table
Add a link
Reference in a new issue