Skip to content

Commit

Permalink
feat: Create internal news page and update existing external news page (
Browse files Browse the repository at this point in the history
#711)

* Update news page layout

* Update tests

* Update test

* Add widget-related jsx and styles back

* Update styles

* Update tests

* Remove unnecessary code

* Update links to open new tab

* Update Label Source color

* Update date

* Add LoadingWidget

* Add internal news page and query

* Update styles

* Update tests

* Update external news page to use ArticleListItem

* Add comment

* Fix link

* Remove unnecessary code

* Remove unnecessary tests

* Update query

* Update Label display

* Update loading state

* Remove comments

* Update tests
  • Loading branch information
jcbcapps authored Jul 28, 2022
1 parent 0e3a674 commit feadcae
Show file tree
Hide file tree
Showing 21 changed files with 324 additions and 230 deletions.
2 changes: 1 addition & 1 deletion e2e/cypress/integration/navigation.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ describe('Routes & navigation', () => {
it('can navigate to the News page', () => {
cy.visit('/news')
cy.injectAxe()
cy.contains('Latest news')
cy.contains('All USSF news')
cy.checkA11y(null, null, logging, { skipFailures: true })
})

Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/pages/news.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ describe('News page', () => {

expect(
await screen.findByRole('heading', { level: 2 })
).toHaveTextContent('Latest news')
).toHaveTextContent('All USSF news')
expect(await screen.findAllByRole('article')).toHaveLength(10)
})
})
Expand Down
17 changes: 12 additions & 5 deletions src/components/ArticleDateIcon/ArticleDateIcon.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,27 @@

.ArticleDateIcon {
border: 1px solid $theme-cosmiclatte-dark;
border-radius: 6px;
background-color: $theme-cosmiclatte-lightest;
border-radius: 8px;
background: $theme-cosmiclatte-lighter;

width: 65px;
padding: units(1);
width: 60px;
height: 60px;
display: flex;
flex-direction: column;
justify-content: space-between;
justify-content: center;
align-items: center;
text-align: center;
text-transform: uppercase;
font-size: size('body', 7);

small {
font-size: size('body', 1);
line-height: 15px;
}

span {
font-family: 'Sharp Sans';
line-height: 23px;
}

* + * {
Expand Down
1 change: 0 additions & 1 deletion src/components/ArticleDateIcon/ArticleDateIcon.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ describe('ArticleDateIcon component', () => {

expect(screen.getByText('May')).toBeInTheDocument()
expect(screen.getByText('16')).toBeInTheDocument()
expect(screen.getByText('2022')).toBeInTheDocument()
})

it('has no a11y violations', async () => {
Expand Down
4 changes: 1 addition & 3 deletions src/components/ArticleDateIcon/ArticleDateIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@ export const ArticleDateIcon = ({ date }: { date: Date }) => {
const dateParts = dateFormatter.formatToParts(date)
const { value: month } = dateParts.find((i) => i.type === 'month') || {}
const { value: day } = dateParts.find((i) => i.type === 'day') || {}
const { value: year } = dateParts.find((i) => i.type === 'year') || {}

if (month === undefined || day === undefined || year === undefined) {
if (month === undefined || day === undefined) {
// TODO throw error
return null
}
Expand All @@ -24,7 +23,6 @@ export const ArticleDateIcon = ({ date }: { date: Date }) => {
<time dateTime={date.toLocaleString()} className={styles.ArticleDateIcon}>
<small>{month}</small>
<span>{day}</span>
<small>{year}</small>
</time>
)
} catch (e) {
Expand Down
28 changes: 11 additions & 17 deletions src/components/ArticleListItem/ArticleListItem.module.scss
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
@import 'styles/uswdsDependencies';
@import 'styles/sfds/sfdsDependencies';

.ArticleListItem {
display: flex;
align-items: flex-start;
.articleTitle {
margin-bottom: 0.5em;
margin-top: 0;

time {
flex-shrink: 0;
}

time + div {
margin-left: units(3);
}

h4,
p {
margin: 0;
a {
color: $theme-black;
text-decoration: none;
}
}

h4 + p {
margin-top: units(1);
}
.categoryAndLabel {
margin-left: 0 !important;
margin-right: 0 !important;
}
5 changes: 2 additions & 3 deletions src/components/ArticleListItem/ArticleListItem.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,9 @@ describe('ArticleListItem component', () => {

expect(screen.getByText('May')).toBeInTheDocument()
expect(screen.getByText('17')).toBeInTheDocument()
expect(screen.getByText('2022')).toBeInTheDocument()

expect(screen.getByRole('link')).toHaveTextContent(testArticle.title)
expect(screen.getByRole('link')).toHaveAttribute(
expect(screen.getAllByText(testArticle.title)).toHaveLength(1)
expect(screen.getByTestId('article-slug')).toHaveAttribute(
'href',
`/articles/${testArticle.slug}`
)
Expand Down
74 changes: 63 additions & 11 deletions src/components/ArticleListItem/ArticleListItem.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,81 @@
import React from 'react'

import { Grid } from '@trussworks/react-uswds'
import styles from './ArticleListItem.module.scss'

import { Category, Label } from 'components/Tag/Tag'
import type { ArticleListItemRecord } from 'types'
import { ArticleDateIcon } from 'components/ArticleDateIcon/ArticleDateIcon'
import LinkTo from 'components/util/LinkTo/LinkTo'
import { CONTENT_CATEGORIES } from 'constants/index'

export const ArticleListItem = ({
article,
}: {
article: ArticleListItemRecord
}) => {
const { slug, title, preview, publishedDate } = article
const {
title,
preview,
publishedDate,
slug,
sourceLink,
source = 'CMS',
sourceName,
labels,
} = article

const publishedDateObj = new Date(publishedDate)

return (
<article className={styles.ArticleListItem}>
<ArticleDateIcon date={publishedDateObj} />
<div>
<h4>
<LinkTo href={`/articles/${slug}`}>{title}</LinkTo>
</h4>
<p>{preview}</p>
</div>
<article>
<Grid row gap={4}>
<Grid col="auto">
<ArticleDateIcon date={publishedDateObj} />
</Grid>

<Grid col="fill" gap="05">
<h3 className={styles.articleTitle}>
<LinkTo
href={sourceLink ? sourceLink : `/articles/${slug}`}
target="_blank"
rel="noreferrer noopener">
{title}
</LinkTo>
</h3>
<LinkTo
href={sourceLink ? sourceLink : `/articles/${slug}`}
target="_blank"
rel="noreferrer noopener"
data-testid="article-slug">
{sourceLink ? sourceLink : `/articles/${slug}`}
</LinkTo>
<p>
<span>{preview}</span>
</p>
<Grid row gap={4} className={styles.categoryAndLabel}>
<Category
category={
source === 'RSS'
? CONTENT_CATEGORIES.EXTERNAL_NEWS
: CONTENT_CATEGORIES.INTERNAL_NEWS
}
/>

{source === 'CMS' && labels && labels.length > 0 && (
<>
{labels.map((label) => {
return (
<Label key={label.id} type={label.type}>
{label.name}
</Label>
)
})}
</>
)}

{source === 'RSS' && <Label type="Source">{sourceName}</Label>}
</Grid>
</Grid>
</Grid>
</article>
)
}
54 changes: 36 additions & 18 deletions src/components/NewsListItem/NewsListItem.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -30,32 +30,50 @@ a.articleLink {
}
}

.articleImage {
border: 1px solid #c4c4c4;
border-radius: 6px;
overflow: hidden;

img {
width: 100%;
display: block;
height: 200px;
object-fit: cover;

@include at-media('tablet') {
height: 360px;
}
.articleTitle {
margin-bottom: 0.5em;
margin-top: 0;

a {
color: $theme-black;
text-decoration: none;
}
}

.articlePublishedDate {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-transform: uppercase;
height: 60px;
width: 60px;
background: $theme-cosmiclatte-lighter;
border: 1px solid $theme-cosmiclatte-dark;
border-radius: 8px;

span.month {
font-size: 12px;
line-height: 15px;
}

span.day {
font-family: 'Sharp Sans';
font-size: 18px;
line-height: 23px;
}
}

.articleImage + .articleLink {
margin-top: units(2);
.categoryAndLabel {
margin-left: 0 !important;
margin-right: 0 !important;
}

.articleExcerpt {
font-size: 18px;
line-height: 1.4;
margin: units('105') 0 units(3);
text-align: right;
margin-bottom: 0;
margin-top: 0;
flex-grow: 1;

.articleExcerptTruncate {
Expand Down
2 changes: 1 addition & 1 deletion src/components/NewsListItem/NewsListItem.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const mockRSSArticle = {
sourceLink:
'https://www.spaceforce.mil/News/Article/2903050/daf-covid-19-statistics-feb-8-2022/',
description: `Space Operations Command has accepted Space Based Geosynchronous Infrared Satellite 5 as operationally capable and has presented it to United States Space Command for operational use.`,
publishDate: '04 Feb 2022',
publishDate: 'Feb 04, 2022',
thumbnailSrc:
'https://media.defense.gov/2021/Dec/07/2002921422/670/394/0/211207-F-GO452-0001.JPG',
source: 'RSS',
Expand Down
Loading

0 comments on commit feadcae

Please sign in to comment.