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

COR-1660-archive-thermometer #4818

Merged
merged 15 commits into from
Jul 18, 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
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { asResponsiveArray } from '~/style/utils';
import { BaseTile } from '~/queries/query-types';
import { getFilenameToIconName } from '~/utils';
import { TOPICAL_SEVERITY_INDICATOR_TILE_MAX_WIDTH } from '../severity-indicator-tile/constants';
import { RichContent } from '../cms/rich-content';

interface TopicalWeeklySummaryTileProps {
label: string | undefined;
Expand All @@ -35,8 +36,8 @@ export const TopicalWeeklySummaryTile = ({ label, level, title, summaryItems }:
<Box minWidth="25px" height="25px">
<DynamicIcon width="25px" name={getFilenameToIconName(summaryItem.tileIcon) as TopicalIcon} />
</Box>
<Box>
<InlineText>{summaryItem.description}</InlineText>
<Box display="flex">
APW26 marked this conversation as resolved.
Show resolved Hide resolved
<RichContent blocks={summaryItem.description} />
{summaryItem.isThermometerMetric && label && (
<InlineText css={css({ whiteSpace: 'nowrap' })}>
<SeverityIndicatorLevel level={level}>{level}</SeverityIndicatorLevel>
Expand All @@ -53,7 +54,7 @@ export const TopicalWeeklySummaryTile = ({ label, level, title, summaryItems }:
};

const SeverityIndicatorLevel = styled.span`
margin: 0 ${space[1]};
margin: 0 ${space[2]};
background-color: ${({ level }: { level: SeverityLevel }) => getSeverityColor(level as SeverityLevels)};
border-radius: 50%;
color: ${colors.white};
Expand Down
1 change: 1 addition & 0 deletions packages/app/src/domain/layout/logic/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export type GmCategoryKeys = SharedCategoryKeys | 'archived_metrics';
export type NlItemKeys =
| 'compliance'
| 'coronamelder_app'
| 'corona_thermometer'
| 'disabled_care'
| 'elderly_at_home'
| 'general_practitioner_suspicions'
Expand Down
1 change: 1 addition & 0 deletions packages/app/src/domain/layout/logic/use-sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const mapCategoriesToIcons = {
const mapKeysToReverseRouter = {
compliance: 'gedrag',
coronamelder_app: 'coronamelder',
corona_thermometer: 'coronaThermometer',
current_advices: 'geldendeAdviezen',
disabled_care: 'gehandicaptenzorg',
elderly_at_home: 'thuiswonendeOuderen',
Expand Down
1 change: 1 addition & 0 deletions packages/app/src/domain/layout/nl-layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export function NlLayout(props: NlLayoutProps) {
[
'nursing_home_care',
'reproduction_number',
'corona_thermometer',
'compliance',
'positive_tests',
'disabled_care',
Expand Down
95 changes: 5 additions & 90 deletions packages/app/src/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,30 @@
import { colors } from '@corona-dashboard/common';
import { IconName as TopicalIcon } from '@corona-dashboard/icons/src/icon-name2filename';
import { css } from '@styled-system/css';
import { GetStaticPropsContext } from 'next';
import styled from 'styled-components';
import { isPresent } from 'ts-is-present';
import { Box, Spacer } from '~/components/base';
import { RichContent } from '~/components/cms/rich-content';
import { CollapsibleSection } from '~/components/collapsible';
import { MaxWidth } from '~/components/max-width';
import { getTimelineRangeDates } from '~/components/severity-indicator-tile/components/timeline/logic';
import { Timeline } from '~/components/severity-indicator-tile/components/timeline/timeline';
import { SEVERITY_LEVELS_LIST, TOPICAL_SEVERITY_INDICATOR_TILE_MAX_WIDTH } from '~/components/severity-indicator-tile/constants';
import { SeverityIndicatorTile } from '~/components/severity-indicator-tile/severity-indicator-tile';
import { SeverityLevel, SeverityLevels } from '~/components/severity-indicator-tile/types';
import { TimelineMarker } from '~/components/time-series-chart/components/timeline';
import { TOPICAL_SEVERITY_INDICATOR_TILE_MAX_WIDTH } from '~/components/severity-indicator-tile/constants';
import { TopicalWeeklySummaryTile } from '~/components/weekly-summary/topical-weekly-summary-tile';
import { Layout } from '~/domain/layout';
import { Advice } from '~/domain/topical/components/advice';
import { IndicatorLevelDescription } from '~/domain/topical/components/indicator-level-description';
import { TopicalArticlesList } from '~/domain/topical/components/topical-article-list';
import { TopicalHeader } from '~/domain/topical/components/topical-header';
import { TopicalTile } from '~/domain/topical/components/topical-kpi-tile/topical-tile';
import { TopicalLinksList } from '~/domain/topical/components/topical-links-list';
import { TopicalSectionHeader } from '~/domain/topical/components/topical-section-header';
import { TopicalThemeHeader } from '~/domain/topical/components/topical-theme-header';
import { TrendIcon } from '~/domain/topical/types';
import { Languages, SiteText } from '~/locale';
import { getArticleParts, getPagePartsQuery } from '~/queries/get-page-parts-query';
import { getThermometerEvents, getTopicalStructureQuery } from '~/queries/get-topical-structure-query';
import { getTopicalStructureQuery } from '~/queries/get-topical-structure-query';
import { TopicalSanityData } from '~/queries/query-types';
import { StaticProps, createGetStaticProps } from '~/static-props/create-get-static-props';
import { createGetContent, getLastGeneratedDate, getLokalizeTexts } from '~/static-props/get-data';
import { space } from '~/style/theme';
import { ArticleParts, LinkParts, PagePartQueryResult, RichTextParts } from '~/types/cms';
import { getFilenameToIconName, replaceVariablesInText } from '~/utils';
import { useDynamicLokalizeTexts } from '~/utils/cms/use-dynamic-lokalize-texts';
import { getThermometerSeverityLevels } from '~/utils/get-thermometer-severity-level';

const selectLokalizeTexts = (siteText: SiteText) => ({
textNl: siteText.pages.topical_page.nl,
Expand Down Expand Up @@ -87,12 +77,7 @@ const Home = (props: StaticProps<typeof getStaticProps>) => {
md: `repeat(3, 1fr)`,
};

const currentSeverityLevel = thermometer.currentLevel as unknown as SeverityLevels;
const currentSeverityLevelTexts = thermometer.thermometerLevels.find((thermometerLevel) => thermometerLevel.level === currentSeverityLevel);

const thermometerEvents = getThermometerEvents(thermometer.timeline.ThermometerTimelineEvents, thermometer.thermometerLevels);

const { startDate, endDate } = getTimelineRangeDates(thermometerEvents);
const { currentSeverityLevel, currentSeverityLevelTexts } = getThermometerSeverityLevels(thermometer);

return (
<Layout {...metadata} lastGenerated={lastGenerated}>
Expand All @@ -110,70 +95,8 @@ const Home = (props: StaticProps<typeof getStaticProps>) => {
<Box paddingX={{ _: space[3], sm: space[4] }} maxWidth={TOPICAL_SEVERITY_INDICATOR_TILE_MAX_WIDTH}>
<TopicalHeader description={topicalConfig.description} />
</Box>
{currentSeverityLevelTexts && (
<Box marginY={space[5]} paddingX={{ _: space[3], sm: space[4] }} maxWidth={TOPICAL_SEVERITY_INDICATOR_TILE_MAX_WIDTH}>
<TopicalThemeHeader title={thermometer.title} subtitle={thermometer.subTitle} icon={getFilenameToIconName(thermometer.icon) as TopicalIcon} />

<SeverityIndicatorTile
level={currentSeverityLevel}
description={
currentSeverityLevelTexts.description &&
replaceVariablesInText(currentSeverityLevelTexts.description, {
label: currentSeverityLevelTexts.label.toLowerCase(),
})
}
title={thermometer.tileTitle}
label={currentSeverityLevelTexts.label}
sourceLabel={thermometer.sourceLabel}
datesLabel={thermometer.datesLabel}
levelDescription={thermometer.levelDescription}
trendIcon={thermometer.trendIcon as TrendIcon}
/>

{thermometerEvents && thermometerEvents.length && (
<Timeline
startDate={startDate}
endDate={endDate}
timelineEvents={thermometerEvents}
labels={{
heading: thermometer.timeline.title,
today: thermometer.timeline.todayLabel,
tooltipCurrentEstimation: thermometer.timeline.tooltipLabel,
}}
legendItems={[
{
label: thermometer.timeline.legendLabel,
shape: 'custom',
shapeComponent: <TimelineMarker color={colors.gray6} />,
},
]}
/>
)}

<Box marginY={{ _: space[3], md: space[4] }} borderBottom={'1px solid'} borderBottomColor={colors.gray3}>
<CollapsibleSection summary={thermometer.collapsibleTitle} textColor={colors.black} borderColor={colors.gray3}>
<Box marginY={space[3]}>
<OrderedList>
{SEVERITY_LEVELS_LIST.map((severityLevel, index) => {
const indicatorTexts = thermometer.thermometerLevels.find((thermometerLevel) => thermometerLevel.level === severityLevel);
return (
indicatorTexts && (
<IndicatorLevelDescription
key={index}
level={indicatorTexts.level as SeverityLevel}
label={indicatorTexts.label}
description={indicatorTexts.description}
/>
)
);
})}
</OrderedList>
</Box>
</CollapsibleSection>
</Box>
<RichContent blocks={thermometer.articleReference} />
</Box>
)}
<Spacer marginBottom={space[5]} />

<Box spacing={{ _: 5, md: 6 }} paddingX={{ _: space[3], sm: space[4] }}>
{kpiThemes.themes.map((theme) => {
VWSCoronaDashboard30 marked this conversation as resolved.
Show resolved Hide resolved
Expand Down Expand Up @@ -245,12 +168,4 @@ const Home = (props: StaticProps<typeof getStaticProps>) => {
);
};

const OrderedList = styled.ol(
css({
listStyleType: 'none',
margin: '0',
padding: '0',
})
);

export default Home;
195 changes: 195 additions & 0 deletions packages/app/src/pages/landelijk/corona-thermometer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
import { Languages, SiteText } from '~/locale';
import { colors } from '@corona-dashboard/common';
import styled from 'styled-components';
import { Box } from '~/components/base';
import { GetStaticPropsContext } from 'next';
import { getTimelineRangeDates } from '~/components/severity-indicator-tile/components/timeline/logic';
import { Timeline } from '~/components/severity-indicator-tile/components/timeline/timeline';
import { SEVERITY_LEVELS_LIST, TOPICAL_SEVERITY_INDICATOR_TILE_MAX_WIDTH } from '~/components/severity-indicator-tile/constants';
import { SeverityIndicatorTile } from '~/components/severity-indicator-tile/severity-indicator-tile';
import { SeverityLevel } from '~/components/severity-indicator-tile/types';
import { TimelineMarker } from '~/components/time-series-chart/components/timeline';
import { IndicatorLevelDescription } from '~/domain/topical/components/indicator-level-description';
import { TrendIcon } from '~/domain/topical/types';
import { getThermometerEvents, getTopicalStructureQuery } from '~/queries/get-topical-structure-query';
import { StaticProps, createGetStaticProps } from '~/static-props/create-get-static-props';
import { createGetContent, getLastGeneratedDate, getLokalizeTexts } from '~/static-props/get-data';
import { ArticleParts, LinkParts, PagePartQueryResult, RichTextParts } from '~/types/cms';
import { TopicalSanityData } from '~/queries/query-types';
import { getArticleParts, getDataExplainedParts, getFaqParts, getPagePartsQuery } from '~/queries/get-page-parts-query';
import { Layout } from '~/domain/layout/layout';
import { NlLayout } from '~/domain/layout/nl-layout';
import { ChartTile, InView, PageInformationBlock, TileList, WarningTile } from '~/components';
import { useDynamicLokalizeTexts } from '~/utils/cms/use-dynamic-lokalize-texts';
import { space } from '~/style/theme';
import { Coronathermometer } from '@corona-dashboard/icons';
import { useIntl } from '~/intl';
import { replaceVariablesInText } from '~/utils/replace-variables-in-text';
import { getPageInformationHeaderContent } from '~/utils/get-page-information-header-content';
import { PageFaqTile } from '~/components/page-faq-tile';
import { PageArticlesTile } from '~/components/articles/page-articles-tile';
import { getThermometerSeverityLevels } from '~/utils/get-thermometer-severity-level';

const selectLokalizeTexts = (siteText: SiteText) => ({
textNl: siteText.pages.corona_thermometer_page.nl,
});

type LokalizeTexts = ReturnType<typeof selectLokalizeTexts>;

export const getStaticProps = createGetStaticProps(
({ locale }: { locale: keyof Languages }) => getLokalizeTexts(selectLokalizeTexts, locale),
getLastGeneratedDate,
async (context: GetStaticPropsContext) => {
const { content } = await createGetContent<{
parts: PagePartQueryResult<ArticleParts | LinkParts | RichTextParts>;
topicalStructure: TopicalSanityData;
}>((context) => {
const { locale } = context;
return `{
"parts": ${getPagePartsQuery('coronathermometer_page')},
"topicalStructure": ${getTopicalStructureQuery(locale)}
}`;
})(context);
return {
content: {
articles: getArticleParts(content.parts.pageParts, 'coronathermometerPageArticles'),
dataExplained: getDataExplainedParts(content.parts.pageParts, 'coronathermometerPageDataExplained'),
faqs: getFaqParts(content.parts.pageParts, 'coronathermometerPageFAQs'),
topicalStructure: content.topicalStructure,
},
};
}
);

const CoronaThermometer = (props: StaticProps<typeof getStaticProps>) => {
const { pageText, content, lastGenerated } = props;

const { topicalStructure } = content;

const { thermometer } = topicalStructure;

const { textNl } = useDynamicLokalizeTexts<LokalizeTexts>(pageText, selectLokalizeTexts);

const metadata = {
...textNl.metadata,
title: textNl.metadata.title,
description: textNl.metadata.description,
};

const { commonTexts } = useIntl();
const { formatDateFromSeconds } = useIntl();

const { currentSeverityLevel, currentSeverityLevelTexts } = getThermometerSeverityLevels(thermometer);

const thermometerEvents = getThermometerEvents(thermometer.timeline.ThermometerTimelineEvents, thermometer.thermometerLevels);

const lastThermometerSetDate = formatDateFromSeconds(thermometerEvents.slice(-1)[0].end, 'weekday-long');

const { startDate, endDate } = getTimelineRangeDates(thermometerEvents);

const hasActiveWarningTile = !!textNl.pagina.belangrijk_bericht;

return (
<Layout {...metadata} lastGenerated={lastGenerated}>
<NlLayout>
<TileList>
<PageInformationBlock
category={commonTexts.sidebar.categories.archived_metrics.title}
title={textNl.pagina.titel}
description={textNl.pagina.description}
icon={<Coronathermometer aria-hidden="true" />}
metadata={{
datumsText: replaceVariablesInText(textNl.pagina.dates, {
current_state: currentSeverityLevel,
end_date: lastThermometerSetDate,
}),
dateOrRange: endDate,
dateOfInsertionUnix: endDate,
dataSources: [textNl.bronnen.rivm],
}}
pageInformationHeader={getPageInformationHeaderContent({
dataExplained: content.dataExplained,
faq: content.faqs,
})}
/>

{hasActiveWarningTile && <WarningTile isFullWidth message={textNl.pagina.belangrijk_bericht} variant="informational"></WarningTile>}

Amber-Taal-Work marked this conversation as resolved.
Show resolved Hide resolved
<ChartTile title={thermometer.title} disableFullscreen>
{currentSeverityLevelTexts && (
<Box maxWidth={TOPICAL_SEVERITY_INDICATOR_TILE_MAX_WIDTH}>
<SeverityIndicatorTile
level={currentSeverityLevel}
description={
currentSeverityLevelTexts.description &&
replaceVariablesInText(currentSeverityLevelTexts.description, {
label: currentSeverityLevelTexts.label.toLowerCase(),
})
}
title={thermometer.tileTitle}
label={currentSeverityLevelTexts.label}
sourceLabel={thermometer.sourceLabel}
datesLabel={thermometer.datesLabel}
levelDescription={thermometer.levelDescription}
trendIcon={thermometer.trendIcon as TrendIcon}
/>
{thermometerEvents && thermometerEvents.length && (
<Timeline
startDate={startDate}
endDate={endDate}
timelineEvents={thermometerEvents}
labels={{
heading: thermometer.timeline.title,
today: thermometer.timeline.todayLabel,
tooltipCurrentEstimation: thermometer.timeline.tooltipLabel,
}}
legendItems={[
{
label: thermometer.timeline.legendLabel,
shape: 'custom',
shapeComponent: <TimelineMarker color={colors.gray6} />,
},
]}
/>
)}
</Box>
)}
</ChartTile>

<ChartTile title={thermometer.collapsibleTitle} disableFullscreen>
<OrderedList>
{SEVERITY_LEVELS_LIST.map((severityLevel, index) => {
const indicatorTexts = thermometer.thermometerLevels.find((thermometerLevel) => thermometerLevel.level === severityLevel);
return (
indicatorTexts && (
<IndicatorLevelDescription key={index} level={indicatorTexts.level as SeverityLevel} label={indicatorTexts.label} description={indicatorTexts.description} />
VWSCoronaDashboard30 marked this conversation as resolved.
Show resolved Hide resolved
)
);
})}
</OrderedList>
</ChartTile>

{content.faqs && content.faqs.questions?.length > 0 && <PageFaqTile questions={content.faqs.questions} title={content.faqs.sectionTitle}></PageFaqTile>}

{content.articles && content.articles.articles?.length > 0 && (
<InView rootMargin="400px">
<PageArticlesTile articles={content.articles.articles} title={content.articles.sectionTitle}></PageArticlesTile>
</InView>
)}
</TileList>
</NlLayout>
</Layout>
);
};

const OrderedList = styled.ol`
margin-top: ${space[4]};
padding: 0;
list-style-type: none;

li:last-child div {
margin: 0;
}
`;

export default CoronaThermometer;
2 changes: 1 addition & 1 deletion packages/app/src/queries/query-types.ts
Jorrik-Klijnsma-Work marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export interface TopicalSanityData {
advice: Advice;
}

interface ThermometerConfig {
export interface ThermometerConfig {
icon: TopicalIcon;
title: string;
subTitle: PortableTextEntry[] | null;
Expand Down
Loading