Skip to content
This repository has been archived by the owner on Nov 4, 2024. It is now read-only.

feature/COR-1601-articles-overview-improved-design #4807

Merged
merged 10 commits into from
Jul 7, 2023
Merged
92 changes: 0 additions & 92 deletions packages/app/src/components/article-teaser.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
import { colors } from '@corona-dashboard/common';
import { css } from '@styled-system/css';
import styled from 'styled-components';
import { ArrowIconLeft } from '~/components/arrow-icon';
import { Box } from '~/components/base';
import { ContentBlock } from '~/components/cms/content-block';
import { Heading, InlineText, Anchor } from '~/components/typography';
import { Anchor, Heading, InlineText } from '~/components/typography';
import { ArticleCategoryType } from '~/domain/topical/common/categories';
import { useIntl } from '~/intl';
import { SiteText } from '~/locale';
import { space } from '~/style/theme';
import { Article } from '~/types/cms';
import { replaceComponentsInText } from '~/utils';
import { Link } from '~/utils/link';
import { mergeAdjacentKpiBlocks } from '~/utils/merge-adjacent-kpi-blocks';
import { ContentImage } from './cms/content-image';
import { RichContent } from './cms/rich-content';
import { LinkWithIcon } from './link-with-icon';
import { PublicationDate } from './publication-date';
import { useBreakpoints } from '~/utils/use-breakpoints';
import { colors } from '@corona-dashboard/common';
import { space } from '~/style/theme';
import { ContentImage } from '../cms/content-image';
import { RichContent } from '../cms/rich-content';
import { LinkWithIcon } from '../link-with-icon';
import { PublicationDate } from '../publication-date';

interface ArticleDetailProps {
article: Article;
text: SiteText['pages']['topical_page']['shared'];
Expand All @@ -43,9 +45,19 @@ export function ArticleDetail({ article, text }: ArticleDetailProps) {

<Box spacing={2}>
<Heading level={1}>{article.title}</Heading>
<InlineText color="gray7">

<Box display="flex" color={colors.gray7}>
<PublicationDate date={article.publicationDate} />
</InlineText>

{article.updatedDate && (
<>
<Box marginX={space[2]} marginBottom="5px">
|
</Box>
<span>{replaceComponentsInText(commonTexts.article_detail.articles_updated_date, { date: <PublicationDate date={article.updatedDate} /> })}</span>
APW26 marked this conversation as resolved.
Show resolved Hide resolved
</>
)}
</Box>
</Box>

<Box textVariant="h4">
Expand Down
137 changes: 137 additions & 0 deletions packages/app/src/components/articles/article-teaser.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import { colors } from '@corona-dashboard/common';
import { ChevronRight } from '@corona-dashboard/icons';
import styled from 'styled-components';
import { useIntl } from '~/intl';
import { mediaQueries, radii, space } from '~/style/theme';
import { Article, ArticleMainCategory, ArticlePublishedDate, ArticleUpdatedDate, Block, ImageBlock } from '~/types/cms';
import { Link } from '~/utils/link';
import { BackgroundImage } from '../background-image';
import { Box } from '../base';
import { Anchor, Heading, Text } from '../typography';
import { ArticleUpdateOrPublishingDate } from './article-update-or-publishing-date';

export type ArticleSummary = Pick<Article, 'title' | 'slug' | 'summary' | 'cover' | 'category' | 'categories' | 'publicationDate' | 'mainCategory' | 'updatedDate'>;

interface ArticleTeaserImageProps {
image: ImageBlock;
sizes: string[][];
}

const ArticleTeaserImage = ({ image, sizes }: ArticleTeaserImageProps) => {
return (
<div className="article-teaser-image">
APW26 marked this conversation as resolved.
Show resolved Hide resolved
<BackgroundImage image={image} height="200px" sizes={sizes} />
</div>
);
};

interface ArticleTeaserProps {
cover: ImageBlock;
coverSizes: string[][];
mainCategory: ArticleMainCategory | null;
publicationDate: ArticlePublishedDate;
slug: string;
summary: Block;
title: string;
updatedDate: ArticleUpdatedDate;
}

export const ArticleTeaser = ({ title, slug, summary, cover, coverSizes, mainCategory, publicationDate, updatedDate }: ArticleTeaserProps) => {
const { commonTexts } = useIntl();

return (
<article>
APW26 marked this conversation as resolved.
Show resolved Hide resolved
<Link passHref href={`/artikelen/${slug}`}>
<ArticleTeaserCard>
{cover.asset && <ArticleTeaserImage image={cover} sizes={coverSizes} />}

<ArticleTeaserContent>
{mainCategory && <Text color={colors.gray8}>{commonTexts.article_teaser.categories[mainCategory]}</Text>}

<Heading level={4} as="h2">
{title}
</Heading>

<Box flexGrow={1}>
<Text>{summary}</Text>
</Box>

<ArticleUpdateOrPublishingDate publishedDate={publicationDate} updatedDate={updatedDate} mainCategory={mainCategory} />

<ArticleCTA aria-hidden="true">
<span>{commonTexts.common.read_more}</span>
APW26 marked this conversation as resolved.
Show resolved Hide resolved
<ChevronRight />
</ArticleCTA>
</ArticleTeaserContent>
</ArticleTeaserCard>
</Link>
</article>
);
};

const ArticleTeaserContent = styled.div`
display: flex;
flex-direction: column;
height: 100%;
padding: ${space[3]} ${space[3]} 0 ${space[3]};

& > * {
margin-bottom: ${space[3]};
}
`;

const ArticleTeaserCard = styled(Anchor)`
border: 1px solid ${colors.gray3};
border-radius: ${radii[2]}px;
color: ${colors.black};
cursor: pointer;
display: flex;
flex-direction: column;
height: 100%;
margin-bottom: ${space[4]};
min-height: 26rem;
overflow: hidden;
text-decoration: none;

@media ${mediaQueries.xs} {
margin-bottom: 0;
}

.article-teaser-image {
flex-shrink: 0;
height: 200px;
overflow: hidden;
position: relative;
}

.article-teaser-image,
${Heading} {
transition: transform 500ms, color 250ms ease-out;
will-change: transform, color;
}

&:hover,
&:focus {
.article-teaser-image {
transform: scale(1.04);
transition: transform 200ms, color 250ms ease-in-out;
}

${Heading} {
color: ${colors.blue8};
}
}
`;

const ArticleCTA = styled.strong`
align-items: center;
color: ${colors.blue8};
display: flex;
justify-content: end;

svg {
height: 10px;
margin: 3px 3px 0;
width: 10px;
}
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { colors } from '@corona-dashboard/common';
import { useIntl } from '~/intl';
import { ArticleMainCategory, ArticlePublishedDate, ArticleUpdatedDate } from '~/types/cms';
import { replaceComponentsInText } from '~/utils/replace-components-in-text';
import { Box } from '../base/box';
import { PublicationDate } from '../publication-date';
import { InlineText } from '../typography';
import { getDateToUse } from './logic/get-date-to-use';

interface ArticlePublishingDateProps {
mainCategory: ArticleMainCategory | null;
publishedDate: ArticlePublishedDate;
updatedDate: ArticleUpdatedDate;
}

export const ArticleUpdateOrPublishingDate = ({ publishedDate, updatedDate, mainCategory }: ArticlePublishingDateProps) => {
const { commonTexts } = useIntl();
const { publishedOrUpdatedDate, isUpdatedAfterPublishing } = getDateToUse(publishedDate, updatedDate, mainCategory);

if (isUpdatedAfterPublishing) {
return (
<Box color={colors.gray8} display="flex">
<span>
APW26 marked this conversation as resolved.
Show resolved Hide resolved
{replaceComponentsInText(commonTexts.article_teaser.articles_updated_date, {
date: <PublicationDate date={publishedOrUpdatedDate} />,
})}
</span>
</Box>
);
}

return (
<InlineText color={colors.gray8}>
<PublicationDate date={publishedOrUpdatedDate} />
APW26 marked this conversation as resolved.
Show resolved Hide resolved
</InlineText>
);
};
Loading