diff --git a/packages/app/schema/gm/vaccine_coverage_per_age_group.json b/packages/app/schema/gm/vaccine_coverage_per_age_group.json index 91a5a31820..d98a04f721 100644 --- a/packages/app/schema/gm/vaccine_coverage_per_age_group.json +++ b/packages/app/schema/gm/vaccine_coverage_per_age_group.json @@ -18,42 +18,53 @@ "additionalProperties": false, "type": "object", "required": [ - "age_group_range", - "autumn_2022_vaccinated_percentage", - "fully_vaccinated_percentage", - "autumn_2022_vaccinated_percentage_label", - "fully_vaccinated_percentage_label", - "birthyear_range", + "vaccination_type", + "birthyear_range_12_plus", + "birthyear_range_18_plus", + "birthyear_range_60_plus", + "vaccinated_percentage_12_plus", + "vaccinated_percentage_12_plus_label", + "vaccinated_percentage_18_plus", + "vaccinated_percentage_18_plus_label", + "vaccinated_percentage_60_plus", + "vaccinated_percentage_60_plus_label", "date_of_insertion_unix", "date_unix" ], "properties": { - "age_group_range": { - "type": "string", - "enum": ["12+", "18+", "60+"] - }, - "autumn_2022_vaccinated_percentage": { - "type": ["integer", "null"] - }, - "fully_vaccinated_percentage": { - "type": ["integer", "null"] + "vaccination_type": { + "type": "string" }, - "booster_shot_percentage": { - "type": ["integer", "null"] + "birthyear_range_12_plus": { + "type": "string", + "pattern": "^[0-9]{4}-[0-9]{4}$|^-[0-9]{4}$|^[0-9]{4}-$" }, - "birthyear_range": { + "birthyear_range_18_plus": { "type": "string", "pattern": "^[0-9]{4}-[0-9]{4}$|^-[0-9]{4}$|^[0-9]{4}-$" }, - "autumn_2022_vaccinated_percentage_label": { + "birthyear_range_60_plus": { + "type": ["string", "null"], + "pattern": "^[0-9]{4}-[0-9]{4}$|^-[0-9]{4}$|^[0-9]{4}-$" + }, + "vaccinated_percentage_12_plus": { + "type": ["number", "null"] + }, + "vaccinated_percentage_12_plus_label": { "type": ["string", "null"], "pattern": "^([><][=][0-9]{1,2})$" }, - "fully_vaccinated_percentage_label": { + "vaccinated_percentage_18_plus": { + "type": ["number", "null"] + }, + "vaccinated_percentage_18_plus_label": { "type": ["string", "null"], "pattern": "^([><][=][0-9]{1,2})$" }, - "booster_shot_percentage_label": { + "vaccinated_percentage_60_plus": { + "type": ["number", "null"] + }, + "vaccinated_percentage_60_plus_label": { "type": ["string", "null"], "pattern": "^([><][=][0-9]{1,2})$" }, diff --git a/packages/app/schema/gm_collection/__index.json b/packages/app/schema/gm_collection/__index.json index 227e4878c8..c8a2d23f05 100644 --- a/packages/app/schema/gm_collection/__index.json +++ b/packages/app/schema/gm_collection/__index.json @@ -57,8 +57,8 @@ }, "vaccine_coverage_per_age_group": { "type": "array", - "minItems": 1032, - "maxItems": 1032, + "minItems": 688, + "maxItems": 688, "items": { "$ref": "vaccine_coverage_per_age_group.json" } diff --git a/packages/app/schema/gm_collection/vaccine_coverage_per_age_group.json b/packages/app/schema/gm_collection/vaccine_coverage_per_age_group.json index fcf937c108..464ecf98b6 100644 --- a/packages/app/schema/gm_collection/vaccine_coverage_per_age_group.json +++ b/packages/app/schema/gm_collection/vaccine_coverage_per_age_group.json @@ -5,12 +5,16 @@ "additionalProperties": false, "required": [ "gmcode", - "age_group_range", - "birthyear_range", - "autumn_2022_vaccinated_percentage", - "autumn_2022_vaccinated_percentage_label", - "fully_vaccinated_percentage", - "fully_vaccinated_percentage_label", + "vaccination_type", + "birthyear_range_12_plus", + "birthyear_range_18_plus", + "birthyear_range_60_plus", + "vaccinated_percentage_12_plus", + "vaccinated_percentage_12_plus_label", + "vaccinated_percentage_18_plus", + "vaccinated_percentage_18_plus_label", + "vaccinated_percentage_60_plus", + "vaccinated_percentage_60_plus_label", "date_of_insertion_unix", "date_unix" ], @@ -19,25 +23,39 @@ "type": "string", "pattern": "^GM[0-9]+$" }, - "age_group_range": { - "type": "string", - "enum": ["12+", "18+", "60+"] - }, - "autumn_2022_vaccinated_percentage": { - "type": ["integer", "null"] + "vaccination_type": { + "type": "string" }, - "fully_vaccinated_percentage": { - "type": ["integer", "null"] + "birthyear_range_12_plus": { + "type": "string", + "pattern": "^[0-9]{4}-[0-9]{4}$|^-[0-9]{4}$|^[0-9]{4}-$" }, - "birthyear_range": { + "birthyear_range_18_plus": { "type": "string", "pattern": "^[0-9]{4}-[0-9]{4}$|^-[0-9]{4}$|^[0-9]{4}-$" }, - "autumn_2022_vaccinated_percentage_label": { + "birthyear_range_60_plus": { + "type": ["string", "null"], + "pattern": "^[0-9]{4}-[0-9]{4}$|^-[0-9]{4}$|^[0-9]{4}-$" + }, + "vaccinated_percentage_12_plus": { + "type": ["number", "null"] + }, + "vaccinated_percentage_12_plus_label": { + "type": ["string", "null"], + "pattern": "^([><][=][0-9]{1,2})$" + }, + "vaccinated_percentage_18_plus": { + "type": ["number", "null"] + }, + "vaccinated_percentage_18_plus_label": { "type": ["string", "null"], "pattern": "^([><][=][0-9]{1,2})$" }, - "fully_vaccinated_percentage_label": { + "vaccinated_percentage_60_plus": { + "type": ["number", "null"] + }, + "vaccinated_percentage_60_plus_label": { "type": ["string", "null"], "pattern": "^([><][=][0-9]{1,2})$" }, diff --git a/packages/app/schema/vr/vaccine_coverage_per_age_group.json b/packages/app/schema/vr/vaccine_coverage_per_age_group.json index 5175980c38..1733d1c6a3 100644 --- a/packages/app/schema/vr/vaccine_coverage_per_age_group.json +++ b/packages/app/schema/vr/vaccine_coverage_per_age_group.json @@ -18,42 +18,53 @@ "additionalProperties": false, "type": "object", "required": [ - "age_group_range", - "autumn_2022_vaccinated_percentage", - "fully_vaccinated_percentage", - "autumn_2022_vaccinated_percentage_label", - "fully_vaccinated_percentage_label", - "birthyear_range", + "vaccination_type", + "birthyear_range_12_plus", + "birthyear_range_18_plus", + "birthyear_range_60_plus", + "vaccinated_percentage_12_plus", + "vaccinated_percentage_12_plus_label", + "vaccinated_percentage_18_plus", + "vaccinated_percentage_18_plus_label", + "vaccinated_percentage_60_plus", + "vaccinated_percentage_60_plus_label", "date_of_insertion_unix", "date_unix" ], "properties": { - "age_group_range": { - "type": "string", - "enum": ["12+", "18+", "60+"] - }, - "autumn_2022_vaccinated_percentage": { - "type": ["integer", "null"] - }, - "fully_vaccinated_percentage": { - "type": ["integer", "null"] + "vaccination_type": { + "type": "string" }, - "booster_shot_percentage": { - "type": ["integer", "null"] + "birthyear_range_12_plus": { + "type": "string", + "pattern": "^[0-9]{4}-[0-9]{4}$|^-[0-9]{4}$|^[0-9]{4}-$" }, - "birthyear_range": { + "birthyear_range_18_plus": { "type": "string", "pattern": "^[0-9]{4}-[0-9]{4}$|^-[0-9]{4}$|^[0-9]{4}-$" }, - "autumn_2022_vaccinated_percentage_label": { + "birthyear_range_60_plus": { + "type": ["string", "null"], + "pattern": "^[0-9]{4}-[0-9]{4}$|^-[0-9]{4}$|^[0-9]{4}-$" + }, + "vaccinated_percentage_12_plus": { + "type": ["number", "null"] + }, + "vaccinated_percentage_12_plus_label": { "type": ["string", "null"], "pattern": "^([><][=][0-9]{1,2})$" }, - "fully_vaccinated_percentage_label": { + "vaccinated_percentage_18_plus": { + "type": ["number", "null"] + }, + "vaccinated_percentage_18_plus_label": { "type": ["string", "null"], "pattern": "^([><][=][0-9]{1,2})$" }, - "booster_shot_percentage_label": { + "vaccinated_percentage_60_plus": { + "type": ["number", "null"] + }, + "vaccinated_percentage_60_plus_label": { "type": ["string", "null"], "pattern": "^([><][=][0-9]{1,2})$" }, diff --git a/packages/app/schema/vr_collection/__index.json b/packages/app/schema/vr_collection/__index.json index f3e8198e6d..10416e6808 100644 --- a/packages/app/schema/vr_collection/__index.json +++ b/packages/app/schema/vr_collection/__index.json @@ -105,8 +105,8 @@ }, "vaccine_coverage_per_age_group": { "type": "array", - "minItems": 75, - "maxItems": 75, + "minItems": 50, + "maxItems": 50, "items": { "$ref": "vaccine_coverage_per_age_group.json" } diff --git a/packages/app/schema/vr_collection/vaccine_coverage_per_age_group.json b/packages/app/schema/vr_collection/vaccine_coverage_per_age_group.json index 5d16ae1613..88915c2007 100644 --- a/packages/app/schema/vr_collection/vaccine_coverage_per_age_group.json +++ b/packages/app/schema/vr_collection/vaccine_coverage_per_age_group.json @@ -5,12 +5,16 @@ "additionalProperties": false, "required": [ "vrcode", - "age_group_range", - "birthyear_range", - "autumn_2022_vaccinated_percentage", - "autumn_2022_vaccinated_percentage_label", - "fully_vaccinated_percentage_label", - "fully_vaccinated_percentage", + "vaccination_type", + "birthyear_range_12_plus", + "birthyear_range_18_plus", + "birthyear_range_60_plus", + "vaccinated_percentage_12_plus", + "vaccinated_percentage_12_plus_label", + "vaccinated_percentage_18_plus", + "vaccinated_percentage_18_plus_label", + "vaccinated_percentage_60_plus", + "vaccinated_percentage_60_plus_label", "date_of_insertion_unix", "date_unix" ], @@ -19,25 +23,39 @@ "type": "string", "pattern": "^VR[0-9]+$" }, - "age_group_range": { - "type": "string", - "enum": ["12+", "18+", "60+"] - }, - "autumn_2022_vaccinated_percentage": { - "type": ["integer", "null"] + "vaccination_type": { + "type": "string" }, - "fully_vaccinated_percentage": { - "type": ["integer", "null"] + "birthyear_range_12_plus": { + "type": "string", + "pattern": "^[0-9]{4}-[0-9]{4}$|^-[0-9]{4}$|^[0-9]{4}-$" }, - "birthyear_range": { + "birthyear_range_18_plus": { "type": "string", "pattern": "^[0-9]{4}-[0-9]{4}$|^-[0-9]{4}$|^[0-9]{4}-$" }, - "autumn_2022_vaccinated_percentage_label": { + "birthyear_range_60_plus": { + "type": ["string", "null"], + "pattern": "^[0-9]{4}-[0-9]{4}$|^-[0-9]{4}$|^[0-9]{4}-$" + }, + "vaccinated_percentage_12_plus": { + "type": ["number", "null"] + }, + "vaccinated_percentage_12_plus_label": { + "type": ["string", "null"], + "pattern": "^([><][=][0-9]{1,2})$" + }, + "vaccinated_percentage_18_plus": { + "type": ["number", "null"] + }, + "vaccinated_percentage_18_plus_label": { "type": ["string", "null"], "pattern": "^([><][=][0-9]{1,2})$" }, - "fully_vaccinated_percentage_label": { + "vaccinated_percentage_60_plus": { + "type": ["number", "null"] + }, + "vaccinated_percentage_60_plus_label": { "type": ["string", "null"], "pattern": "^([><][=][0-9]{1,2})$" }, diff --git a/packages/app/src/components/choropleth/logic/thresholds.ts b/packages/app/src/components/choropleth/logic/thresholds.ts index 465b87704f..8775e41609 100644 --- a/packages/app/src/components/choropleth/logic/thresholds.ts +++ b/packages/app/src/components/choropleth/logic/thresholds.ts @@ -1,9 +1,6 @@ import { colors } from '@corona-dashboard/common'; import { MapType } from '~/components/choropleth/logic'; -import { - BehaviorIdentifier, - behaviorIdentifiers, -} from '~/domain/behavior/logic/behavior-types'; +import { BehaviorIdentifier, behaviorIdentifiers } from '~/domain/behavior/logic/behavior-types'; const positiveTestedThresholds: ChoroplethThresholdsValue[] = [ { @@ -376,21 +373,21 @@ type Thresholds = Record>; export const thresholds: Thresholds = { gm: { infected_per_100k: positiveTestedThresholds, - admissions_on_date_of_admission_per_100000: - hospitalAdmissionsPer100000Thresholds, + admissions_on_date_of_admission_per_100000: hospitalAdmissionsPer100000Thresholds, admissions_on_date_of_admission: hospitalAdmissionsThresholds, elderly_at_home: elderlyAtHomeThresholds, average: sewerThresholds, fully_vaccinated_percentage: vaccineCoveragePercentageThresholds, - has_one_shot_percentage: vaccineCoveragePercentageThresholds, - booster_shot_percentage: vaccineCoveragePercentageThresholds, + primary_series_percentage: vaccineCoveragePercentageThresholds, autumn_2022_vaccinated_percentage: vaccineCoveragePercentageThresholds, + vaccinated_percentage_12_plus: vaccineCoveragePercentageThresholds, + vaccinated_percentage_18_plus: vaccineCoveragePercentageThresholds, + vaccinated_percentage_60_plus: vaccineCoveragePercentageThresholds, }, vr: { infected_per_100k: positiveTestedThresholds, admissions_on_date_of_admission: vrHospitalAdmissionsThresholds, - admissions_on_date_of_admission_per_100000: - hospitalAdmissionsPer100000Thresholds, + admissions_on_date_of_admission_per_100000: hospitalAdmissionsPer100000Thresholds, infected_locations_percentage: infectedLocationsPercentageThresholds, average: sewerThresholds, positive_tested_daily_per_100k: elderlyAtHomeThresholds, @@ -404,22 +401,17 @@ export const thresholds: Thresholds = { travel: situationsThreshold, hospitality: situationsThreshold, fully_vaccinated_percentage: vaccineCoveragePercentageThresholds, - has_one_shot_percentage: vaccineCoveragePercentageThresholds, - booster_shot_percentage: vaccineCoveragePercentageThresholds, + primary_series_percentage: vaccineCoveragePercentageThresholds, autumn_2022_vaccinated_percentage: vaccineCoveragePercentageThresholds, + vaccinated_percentage_12_plus: vaccineCoveragePercentageThresholds, + vaccinated_percentage_18_plus: vaccineCoveragePercentageThresholds, + vaccinated_percentage_60_plus: vaccineCoveragePercentageThresholds, other: situationsThreshold, - ...(Object.fromEntries( - behaviorIdentifiers.map((key) => [ - `${key}_support`, - behaviorSupportThresholds, - ]) - ) as Record<`${BehaviorIdentifier}_support`, ChoroplethThresholdsValue[]>), - ...(Object.fromEntries( - behaviorIdentifiers.map((key) => [ - `${key}_compliance`, - behaviorComplianceThresholds, - ]) - ) as Record< + ...(Object.fromEntries(behaviorIdentifiers.map((key) => [`${key}_support`, behaviorSupportThresholds])) as Record< + `${BehaviorIdentifier}_support`, + ChoroplethThresholdsValue[] + >), + ...(Object.fromEntries(behaviorIdentifiers.map((key) => [`${key}_compliance`, behaviorComplianceThresholds])) as Record< `${BehaviorIdentifier}_compliance`, ChoroplethThresholdsValue[] >), diff --git a/packages/app/src/components/choropleth/tooltips/tooltip-subject.tsx b/packages/app/src/components/choropleth/tooltips/tooltip-subject.tsx index 6946490c56..3ae6733424 100644 --- a/packages/app/src/components/choropleth/tooltips/tooltip-subject.tsx +++ b/packages/app/src/components/choropleth/tooltips/tooltip-subject.tsx @@ -4,6 +4,7 @@ import { ReactNode } from 'react'; import { isDefined, isPresent } from 'ts-is-present'; import { Box } from '~/components/base'; import { BoldText } from '~/components/typography'; +import { space } from '~/style/theme'; import { getThresholdValue } from '~/utils/get-threshold-value'; interface TooltipSubjectProps { @@ -26,17 +27,17 @@ export function TooltipSubject({ subject, thresholdValues, filterBelow, children {subject && {subject}} {children} - + ); diff --git a/packages/app/src/domain/vaccine/common.ts b/packages/app/src/domain/vaccine/common.ts index f20a5929ab..47a0b67a7a 100644 --- a/packages/app/src/domain/vaccine/common.ts +++ b/packages/app/src/domain/vaccine/common.ts @@ -1,4 +1,4 @@ -import { colors } from '@corona-dashboard/common'; +import { colors, GmCollectionVaccineCoveragePerAgeGroup, VrCollectionVaccineCoveragePerAgeGroup } from '@corona-dashboard/common'; export const COLOR_FULLY_VACCINATED = colors.scale.blueDetailed[3]; export const COLOR_FULLY_BOOSTERED = colors.scale.blue[5]; @@ -9,15 +9,37 @@ export const ARCHIVED_COLORS = { COLOR_FULLY_VACCINATED: colors.primary, }; -type FullyVaccinatedAges = '12+' | '18+'; -type Autumn2022Vaccinated = '12+' | '60+'; +// set Age groups once inside AllAgeGroups and use them on the AgeGroups type and variable +const AllAgeGroups = ['12', '18', '60'] as const; +type AgeGroupsCombined = typeof AllAgeGroups; +export type AgeGroups = AgeGroupsCombined[number]; +export const ageGroups = Object.values(AllAgeGroups); + +type PrimarySeriesVaccinatedAges = Extract; +type Autumn2022Vaccinated = Extract; type MatchingVaccineCoverageAgeGroupsType = { - autumn_2022_vaccinated_percentage: Autumn2022Vaccinated[]; - fully_vaccinated_percentage: FullyVaccinatedAges[]; + autumn_2022: Autumn2022Vaccinated[]; + primary_series: PrimarySeriesVaccinatedAges[]; }; +export type VaccineCoverageData = GmCollectionVaccineCoveragePerAgeGroup | VrCollectionVaccineCoveragePerAgeGroup; + export const matchingAgeGroups: MatchingVaccineCoverageAgeGroupsType = { - autumn_2022_vaccinated_percentage: ['12+', '60+'], - fully_vaccinated_percentage: ['12+', '18+'], + autumn_2022: ['60', '12'], + primary_series: ['18', '12'], +}; + +export type PercentageKeysOfAgeGroups = Pick; + +export type PercentageLabelKeysOfAgeGroups = Pick< + VaccineCoverageData, + 'vaccinated_percentage_12_plus_label' | 'vaccinated_percentage_18_plus_label' | 'vaccinated_percentage_60_plus_label' +>; +export type BirthyearRangeKeysOfAgeGroups = Pick; + +export type DataPerAgeGroup = { + birthyear_range_plus: BirthyearRangeKeysOfAgeGroups; + vaccinated_percentage_plus: PercentageKeysOfAgeGroups; + vaccinated_percentage_plus_label: PercentageLabelKeysOfAgeGroups; }; diff --git a/packages/app/src/domain/vaccine/components/age-group-select.tsx b/packages/app/src/domain/vaccine/components/age-group-select.tsx index 35262b893c..6a3c6de0bd 100644 --- a/packages/app/src/domain/vaccine/components/age-group-select.tsx +++ b/packages/app/src/domain/vaccine/components/age-group-select.tsx @@ -8,19 +8,19 @@ import { useIntl } from '~/intl'; import { replaceVariablesInText } from '~/utils/replace-variables-in-text'; import { parseBirthyearRange } from '../logic/parse-birthyear-range'; -export type AgeGroup = '12+' | '18+' | '60+'; +export type AgeGroup = '12' | '18' | '60'; const AGE_GROUPS = [ { - ageGroup: '60+', + ageGroup: '60', birthyearRange: '-1961', }, { - ageGroup: '18+', + ageGroup: '18', birthyearRange: '-2003', }, { - ageGroup: '12+', + ageGroup: '12', birthyearRange: '-2009', }, ] as const; @@ -32,7 +32,7 @@ type AgeGroupSelectProps = { }; export function AgeGroupSelect(props: AgeGroupSelectProps) { - const { onChange, initialValue = '18+', shownAgeGroups } = props; + const { onChange, initialValue = '18', shownAgeGroups } = props; const { commonTexts } = useIntl(); diff --git a/packages/app/src/domain/vaccine/components/vaccination-coverage-kind-select.tsx b/packages/app/src/domain/vaccine/components/vaccination-coverage-kind-select.tsx index c4aca57eaf..88c3a49760 100644 --- a/packages/app/src/domain/vaccine/components/vaccination-coverage-kind-select.tsx +++ b/packages/app/src/domain/vaccine/components/vaccination-coverage-kind-select.tsx @@ -6,24 +6,17 @@ import { Option } from '~/components/rich-content-select/types'; import { Text } from '~/components/typography'; import { useIntl } from '~/intl'; -export type CoverageKindProperty = - | 'autumn_2022_vaccinated_percentage' - | 'fully_vaccinated_percentage'; +export type CoverageKindProperty = 'autumn_2022' | 'primary_series'; -const COVERAGE_KINDS: CoverageKindProperty[] = [ - 'autumn_2022_vaccinated_percentage', - 'fully_vaccinated_percentage', -]; +const COVERAGE_KINDS: CoverageKindProperty[] = ['autumn_2022', 'primary_series']; type VaccinationCoverageKindSelectProps = { onChange: (value: CoverageKindProperty) => void; initialValue?: CoverageKindProperty; }; -export function VaccinationCoverageKindSelect( - props: VaccinationCoverageKindSelectProps -) { - const { onChange, initialValue = 'fully_vaccinated_percentage' } = props; +export function VaccinationCoverageKindSelect(props: VaccinationCoverageKindSelectProps) { + const { onChange, initialValue = 'primary_series' } = props; const { commonTexts } = useIntl(); diff --git a/packages/app/src/domain/vaccine/data-selection/select-vaccine-coverage-data.ts b/packages/app/src/domain/vaccine/data-selection/select-vaccine-coverage-data.ts deleted file mode 100644 index d97211f8e1..0000000000 --- a/packages/app/src/domain/vaccine/data-selection/select-vaccine-coverage-data.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { - GmCollectionVaccineCoveragePerAgeGroup, - VrCollectionVaccineCoveragePerAgeGroup, - VrVaccineCoveragePerAgeGroupValue, -} from '@corona-dashboard/common'; -import { isPresent } from 'ts-is-present'; -import { parseVaccinatedPercentageLabel } from '../logic/parse-vaccinated-percentage-label'; - -export function selectVaccineCoverageData< - T extends - | GmCollectionVaccineCoveragePerAgeGroup - | VrCollectionVaccineCoveragePerAgeGroup - | VrVaccineCoveragePerAgeGroupValue ->(data: T[]) { - return data.map((vaccineCoveragePerAgeGroup) => { - const parsedLabels: { - fully_vaccinated_percentage?: number; - autumn_2022_vaccinated_percentage?: number; - } = {}; - - if (isPresent(vaccineCoveragePerAgeGroup.fully_vaccinated_percentage_label)) { - const result = parseVaccinatedPercentageLabel( - vaccineCoveragePerAgeGroup.fully_vaccinated_percentage_label - ); - - if (isPresent(result)) { - parsedLabels.fully_vaccinated_percentage = - result.sign === '>' ? 100 : 0; - } - } - - if (isPresent(vaccineCoveragePerAgeGroup.autumn_2022_vaccinated_percentage_label)) { - const result = parseVaccinatedPercentageLabel( - vaccineCoveragePerAgeGroup.autumn_2022_vaccinated_percentage_label - ); - - if (isPresent(result)) { - parsedLabels.autumn_2022_vaccinated_percentage = - result.sign === '>' ? 100 : 0; - } - } - - return { ...vaccineCoveragePerAgeGroup, ...parsedLabels }; - }); -} diff --git a/packages/app/src/domain/vaccine/index.ts b/packages/app/src/domain/vaccine/index.ts index 6053218406..dda47aab72 100644 --- a/packages/app/src/domain/vaccine/index.ts +++ b/packages/app/src/domain/vaccine/index.ts @@ -1,5 +1,4 @@ export { selectAdministrationData } from './data-selection/select-administration-data'; -export { selectVaccineCoverageData } from './data-selection/select-vaccine-coverage-data'; export { BoosterShotCoveragePerAgeGroup } from './booster-shot-coverage-per-age-group/booster-shot-coverage-per-age-group'; export { Autumn2022ShotCoveragePerAgeGroup } from './autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group'; export { VaccinationsOverTimeTile } from './vaccinations-over-time-tile'; diff --git a/packages/app/src/domain/vaccine/logic/use-agegroup-labels.ts b/packages/app/src/domain/vaccine/logic/use-agegroup-labels.ts deleted file mode 100644 index 97037ae019..0000000000 --- a/packages/app/src/domain/vaccine/logic/use-agegroup-labels.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { - GmVaccineCoveragePerAgeGroupValue, - VrVaccineCoveragePerAgeGroupValue, -} from '@corona-dashboard/common'; -import { useMemo } from 'react'; -import { isDefined } from 'ts-is-present'; -import { useIntl } from '~/intl'; -import { getRenderedVaccinatedLabel } from './parse-vaccinated-percentage-label'; - -export function useAgegroupLabels( - dataValue: - | VrVaccineCoveragePerAgeGroupValue - | GmVaccineCoveragePerAgeGroupValue - | undefined, - lowerCased?: boolean -) { - const { commonTexts, formatPercentage } = useIntl(); - const labelsText = commonTexts.common; - - return useMemo(() => { - const fullyVaccinatedLabel = isDefined(dataValue) - ? getRenderedVaccinatedLabel( - dataValue.fully_vaccinated_percentage_label, - dataValue.fully_vaccinated_percentage, - labelsText.meer_dan, - labelsText.minder_dan, - formatPercentage - ) - : '0'; - const oneShotLabel = isDefined(dataValue) - ? getRenderedVaccinatedLabel( - dataValue.autumn_2022_vaccinated_percentage_label, - dataValue.autumn_2022_vaccinated_percentage, - labelsText.meer_dan, - labelsText.minder_dan, - formatPercentage - ) - : '0'; - - return { - fully_vaccinated_percentage: lowerCased - ? fullyVaccinatedLabel.toLocaleLowerCase() - : fullyVaccinatedLabel, - autumn_2022_vaccinated_percentage: lowerCased - ? oneShotLabel.toLocaleLowerCase() - : oneShotLabel, - }; - }, [ - dataValue, - labelsText.meer_dan, - labelsText.minder_dan, - formatPercentage, - lowerCased, - ]); -} diff --git a/packages/app/src/domain/vaccine/vaccine-coverage-choropleth.tsx b/packages/app/src/domain/vaccine/vaccine-coverage-choropleth.tsx index 1325aadc7a..b8b4c4b66c 100644 --- a/packages/app/src/domain/vaccine/vaccine-coverage-choropleth.tsx +++ b/packages/app/src/domain/vaccine/vaccine-coverage-choropleth.tsx @@ -1,9 +1,9 @@ import { colors, GmCollectionVaccineCoveragePerAgeGroup, VrCollectionVaccineCoveragePerAgeGroup } from '@corona-dashboard/common'; import { SiteText } from '~/locale'; -import { matchingAgeGroups } from './common'; +import { matchingAgeGroups, VaccineCoverageData, DataPerAgeGroup, BirthyearRangeKeysOfAgeGroups, PercentageKeysOfAgeGroups, PercentageLabelKeysOfAgeGroups } from './common'; import css from '@styled-system/css'; import { useState } from 'react'; -import { hasValueAtKey } from 'ts-is-present'; +import { space } from '~/style/theme'; import { Box } from '~/components/base'; import { RegionControlOption } from '~/components/chart-region-controls'; import { DynamicChoropleth } from '~/components/choropleth'; @@ -18,7 +18,7 @@ import { replaceVariablesInText } from '~/utils/replace-variables-in-text'; import { useReverseRouter } from '~/utils/use-reverse-router'; import { AgeGroup, AgeGroupSelect } from './components/age-group-select'; import { CoverageKindProperty, VaccinationCoverageKindSelect } from './components/vaccination-coverage-kind-select'; -import { useVaccineCoveragePercentageFormatter } from './logic/use-vaccine-coverage-percentage-formatter'; +import { parseVaccinatedPercentageLabel } from './logic/parse-vaccinated-percentage-label'; interface VaccineCoverageChoroplethProps { data: { @@ -30,8 +30,8 @@ interface VaccineCoverageChoroplethProps { export const VaccineCoverageChoropleth = ({ data }: VaccineCoverageChoroplethProps) => { const { commonTexts } = useIntl(); const [selectedMap, setSelectedMap] = useState('gm'); - const [selectedAgeGroup, setSelectedAgeGroup] = useState('18+'); - const [selectedCoverageKind, setSelectedCoverageKind] = useState('fully_vaccinated_percentage'); + const [selectedAgeGroup, setSelectedAgeGroup] = useState('18'); + const [selectedCoverageKind, setSelectedCoverageKind] = useState('primary_series'); const reverseRouter = useReverseRouter(); /** @@ -40,8 +40,8 @@ export const VaccineCoverageChoropleth = ({ data }: VaccineCoverageChoroplethPro */ const setSelectedCoverageKindAndAge = (coverageKind: CoverageKindProperty) => { if (coverageKind === selectedCoverageKind) return; - if (selectedAgeGroup !== '12+') { - setSelectedAgeGroup(selectedAgeGroup === '18+' ? '60+' : '18+'); + if (selectedAgeGroup !== '12') { + setSelectedAgeGroup(selectedAgeGroup === '18' ? '60' : '18'); } setSelectedCoverageKind(coverageKind); }; @@ -50,8 +50,8 @@ export const VaccineCoverageChoropleth = ({ data }: VaccineCoverageChoroplethPro regio: commonTexts.choropleth.choropleth_vaccination_coverage.shared[selectedMap], }; - const choroplethDataVr: VrCollectionVaccineCoveragePerAgeGroup[] = data.vr.filter(hasValueAtKey('age_group_range', selectedAgeGroup)); - const choroplethDataGm: GmCollectionVaccineCoveragePerAgeGroup[] = data.gm.filter(hasValueAtKey('age_group_range', selectedAgeGroup)); + const choroplethDataVr: VrCollectionVaccineCoveragePerAgeGroup[] = data.vr.filter((choroplethDataSingleVR) => choroplethDataSingleVR.vaccination_type === selectedCoverageKind); + const choroplethDataGm: GmCollectionVaccineCoveragePerAgeGroup[] = data.gm.filter((choroplethDataSingleGM) => choroplethDataSingleGM.vaccination_type === selectedCoverageKind); return ( {commonTexts.choropleth.vaccination_coverage.shared.dropdowns_title} @@ -82,12 +82,15 @@ export const VaccineCoverageChoropleth = ({ data }: VaccineCoverageChoroplethPro } legend={{ - thresholds: thresholds.gm.fully_vaccinated_percentage, + thresholds: selectedMap === 'gm' ? thresholds.gm.primary_series_percentage : thresholds.vr.primary_series_percentage, title: commonTexts.choropleth.choropleth_vaccination_coverage.shared.legend_title, }} metadata={{ source: commonTexts.choropleth.vaccination_coverage.shared.bronnen.rivm, - date: data[selectedMap][0].date_unix, + date: + selectedMap === 'gm' + ? data.gm.find((item: GmCollectionVaccineCoveragePerAgeGroup | VrCollectionVaccineCoveragePerAgeGroup) => item.vaccination_type === selectedCoverageKind)?.date_unix + : data.vr.find((item: GmCollectionVaccineCoveragePerAgeGroup | VrCollectionVaccineCoveragePerAgeGroup) => item.vaccination_type === selectedCoverageKind)?.date_unix, }} chartRegion={selectedMap} onChartRegionChange={setSelectedMap} @@ -99,20 +102,13 @@ export const VaccineCoverageChoropleth = ({ data }: VaccineCoverageChoroplethPro data={choroplethDataGm} dataConfig={{ metricName: 'vaccine_coverage_per_age_group', - metricProperty: selectedCoverageKind, + metricProperty: `vaccinated_percentage_${selectedAgeGroup}_plus`, }} dataOptions={{ isPercentage: true, getLink: (gmcode) => reverseRouter.gm.vaccinaties(gmcode), }} - formatTooltip={(context) => ( - singleGM.gmcode === context.code)} - ageGroups={matchingAgeGroups[selectedCoverageKind]} - selectedCoverageKind={selectedCoverageKind} - /> - )} + formatTooltip={(context) => } /> )} @@ -123,74 +119,79 @@ export const VaccineCoverageChoropleth = ({ data }: VaccineCoverageChoroplethPro data={choroplethDataVr} dataConfig={{ metricName: 'vaccine_coverage_per_age_group', - metricProperty: selectedCoverageKind, + metricProperty: `vaccinated_percentage_${selectedAgeGroup}_plus`, }} dataOptions={{ isPercentage: true, getLink: (vrcode) => reverseRouter.vr.vaccinaties(vrcode), }} - formatTooltip={(context) => ( - singleVR.vrcode === context.code)} - ageGroups={matchingAgeGroups[selectedCoverageKind]} - selectedCoverageKind={selectedCoverageKind} - /> - )} + formatTooltip={(context) => } /> )} ); }; -type VaccineCoverageData = GmCollectionVaccineCoveragePerAgeGroup | VrCollectionVaccineCoveragePerAgeGroup; - type ChoroplethTooltipProps = { data: TooltipData; selectedCoverageKind: CoverageKindProperty; ageGroups: AgeGroup[]; - mapData: GmCollectionVaccineCoveragePerAgeGroup[] | VrCollectionVaccineCoveragePerAgeGroup[]; }; -export function ChoroplethTooltip({ data, ageGroups, selectedCoverageKind, mapData }: ChoroplethTooltipProps) { - const { commonTexts } = useIntl(); +export function ChoroplethTooltip({ data, selectedCoverageKind, ageGroups }: ChoroplethTooltipProps) { + const { commonTexts, formatPercentage } = useIntl(); const coverageKindsText = commonTexts.vaccinations.coverage_kinds; const ageGroupsText: SiteText['common']['common']['age_groups'] = commonTexts.common.age_groups; - const formatCoveragePercentage = useVaccineCoveragePercentageFormatter(); - - const secondaryContent = mapData - .sort((a, b) => { - const age1 = Number(a.age_group_range.replace(/\D/g, '')); - const age2 = Number(b.age_group_range.replace(/\D/g, '')); - return age2 - age1; // This logic does not reflect the business logic properly.It matches the business logic right now because for both campaigns the older age group happens to be the primary focus group. This might not be the case for a new campaign. - }) - .map((vrOrGmData) => { - const selectionMatchesAgeGroup = ageGroups.includes(vrOrGmData.age_group_range); - - if (!selectionMatchesAgeGroup) { - return; - } - const filterBelow = vrOrGmData[selectedCoverageKind]; + const tooltipContentValues = ageGroups.map((ageGroup) => { + const ageGroupKeys: DataPerAgeGroup = { + birthyear_range_plus: `birthyear_range_${ageGroup}_plus` as unknown as BirthyearRangeKeysOfAgeGroups, + vaccinated_percentage_plus: `vaccinated_percentage_${ageGroup}_plus` as unknown as PercentageKeysOfAgeGroups, + vaccinated_percentage_plus_label: `vaccinated_percentage_${ageGroup}_plus_label` as unknown as PercentageLabelKeysOfAgeGroups, + }; - return ( - - - - - - - {formatCoveragePercentage(vrOrGmData, selectedCoverageKind)} - + const parsedLabel: { + vaccinated_percentage_plus_label?: string | null; + } = {}; + + const ageGroupPercentage = data.dataItem[ageGroupKeys.vaccinated_percentage_plus as unknown as keyof VaccineCoverageData] as number; + const coveragePercentageLabel = data.dataItem[ageGroupKeys.vaccinated_percentage_plus_label as unknown as keyof VaccineCoverageData] as string; + const minWidthOfLabel = coveragePercentageLabel !== null ? '120px' : undefined; + + const result = coveragePercentageLabel ? parseVaccinatedPercentageLabel(coveragePercentageLabel) : null; + + if (result) { + const content = result.sign === '>' ? commonTexts.common.meer_dan : commonTexts.common.minder_dan; + parsedLabel.vaccinated_percentage_plus_label = replaceVariablesInText(content, { + value: `${formatPercentage(ageGroupPercentage)}%`, + }); + } + + return ( + + + + - - ); - }); + {typeof ageGroupPercentage === 'number' && ( + + {parsedLabel.vaccinated_percentage_plus_label ? parsedLabel.vaccinated_percentage_plus_label : `${formatPercentage(ageGroupPercentage)}%`} + + )} + + + ); + }); return ( {coverageKindsText[selectedCoverageKind]} - {secondaryContent} + {tooltipContentValues} ); } diff --git a/packages/app/src/domain/vaccine/vaccine-coverage-choropleth_vr_and_gm.tsx b/packages/app/src/domain/vaccine/vaccine-coverage-choropleth_vr_and_gm.tsx new file mode 100644 index 0000000000..dece3be298 --- /dev/null +++ b/packages/app/src/domain/vaccine/vaccine-coverage-choropleth_vr_and_gm.tsx @@ -0,0 +1,159 @@ +import { colors, GmCollectionVaccineCoveragePerAgeGroup } from '@corona-dashboard/common'; +import { SiteText } from '~/locale'; +import { matchingAgeGroups, VaccineCoverageData, DataPerAgeGroup, BirthyearRangeKeysOfAgeGroups, PercentageKeysOfAgeGroups, PercentageLabelKeysOfAgeGroups } from './common'; +import css from '@styled-system/css'; +import { useState } from 'react'; +import { space } from '~/style/theme'; +import { Box } from '~/components/base'; +import { DataOptions, DynamicChoropleth } from '~/components/choropleth'; +import { ChoroplethTile } from '~/components/choropleth-tile'; +import { thresholds } from '~/components/choropleth/logic'; +import { TooltipContent, TooltipSubject } from '~/components/choropleth/tooltips'; +import { TooltipData } from '~/components/choropleth/tooltips/types'; +import { Markdown } from '~/components/markdown'; +import { BoldText } from '~/components/typography'; +import { useIntl } from '~/intl'; +import { replaceVariablesInText } from '~/utils/replace-variables-in-text'; +import { AgeGroup, AgeGroupSelect } from './components/age-group-select'; +import { CoverageKindProperty, VaccinationCoverageKindSelect } from './components/vaccination-coverage-kind-select'; +import { parseVaccinatedPercentageLabel } from './logic/parse-vaccinated-percentage-label'; + +interface VaccineCoverageChoroplethProps { + data: GmCollectionVaccineCoveragePerAgeGroup[]; + vrOrGmOptions: { + dataOptions: DataOptions; + text: { + title: string; + description: string; + }; + }; +} + +export const VaccineCoverageChoroplethVrAndGm = ({ data, vrOrGmOptions }: VaccineCoverageChoroplethProps) => { + const { commonTexts } = useIntl(); + const [selectedAgeGroup, setSelectedAgeGroup] = useState('18'); + const [selectedCoverageKind, setSelectedCoverageKind] = useState('primary_series'); + + const setSelectedCoverageKindAndAge = (coverageKind: CoverageKindProperty) => { + if (coverageKind === selectedCoverageKind) return; + if (selectedAgeGroup !== '12') { + setSelectedAgeGroup(selectedAgeGroup === '18' ? '60' : '18'); + } + setSelectedCoverageKind(coverageKind); + }; + + const choroplethDataGm: GmCollectionVaccineCoveragePerAgeGroup[] = data.filter((choroplethDataSingleGM) => choroplethDataSingleGM.vaccination_type === selectedCoverageKind); + + return ( + + + + + {commonTexts.choropleth.vaccination_coverage.shared.dropdowns_title} + + + + + + + + + + + + + + + } + legend={{ + thresholds: thresholds.gm.primary_series_percentage, + title: commonTexts.choropleth.choropleth_vaccination_coverage.shared.legend_title, + }} + metadata={{ + source: commonTexts.choropleth.vaccination_coverage.shared.bronnen.rivm, + date: data.find((item) => item.vaccination_type === selectedCoverageKind)?.date_unix, + }} + hasPadding + > + } + /> + + ); +}; + +type ChoroplethTooltipProps = { + data: TooltipData; + selectedCoverageKind: CoverageKindProperty; + ageGroups: AgeGroup[]; +}; + +export function ChoroplethTooltip({ data, selectedCoverageKind, ageGroups }: ChoroplethTooltipProps) { + const { commonTexts, formatPercentage } = useIntl(); + const coverageKindsText = commonTexts.vaccinations.coverage_kinds; + const ageGroupsText: SiteText['common']['common']['age_groups'] = commonTexts.common.age_groups; + + const secondaryContent = ageGroups.map((ageGroup) => { + const ageGroupKeys: DataPerAgeGroup = { + birthyear_range_plus: `birthyear_range_${ageGroup}_plus` as unknown as BirthyearRangeKeysOfAgeGroups, + vaccinated_percentage_plus: `vaccinated_percentage_${ageGroup}_plus` as unknown as PercentageKeysOfAgeGroups, + vaccinated_percentage_plus_label: `vaccinated_percentage_${ageGroup}_plus_label` as unknown as PercentageLabelKeysOfAgeGroups, + }; + + const parsedLabel: { + vaccinated_percentage_plus_label?: string | null; + } = {}; + + const ageGroupPercentage = data.dataItem[ageGroupKeys.vaccinated_percentage_plus as unknown as keyof VaccineCoverageData] as number; + const coveragePercentageLabel = data.dataItem[ageGroupKeys.vaccinated_percentage_plus_label as unknown as keyof VaccineCoverageData] as string; + const minWidthOfLabel = coveragePercentageLabel !== null ? '120px' : undefined; + + const result = coveragePercentageLabel ? parseVaccinatedPercentageLabel(coveragePercentageLabel) : null; + + if (result) { + const content = result.sign === '>' ? commonTexts.common.meer_dan : commonTexts.common.minder_dan; + parsedLabel.vaccinated_percentage_plus_label = replaceVariablesInText(content, { + value: `${formatPercentage(ageGroupPercentage)}%`, + }); + } + + return ( + + + + + + {typeof ageGroupPercentage === 'number' && ( + + {parsedLabel.vaccinated_percentage_plus_label ? parsedLabel.vaccinated_percentage_plus_label : `${formatPercentage(ageGroupPercentage)}%`} + + )} + + + ); + }); + + return ( + + {coverageKindsText[selectedCoverageKind]} + {secondaryContent} + + ); +} diff --git a/packages/app/src/domain/vaccine/vaccine-coverage-tile/vaccine-coverage-tile.tsx b/packages/app/src/domain/vaccine/vaccine-coverage-tile/vaccine-coverage-tile.tsx index 776d3bdd68..0ac353635a 100644 --- a/packages/app/src/domain/vaccine/vaccine-coverage-tile/vaccine-coverage-tile.tsx +++ b/packages/app/src/domain/vaccine/vaccine-coverage-tile/vaccine-coverage-tile.tsx @@ -20,9 +20,9 @@ type BarType = { color: string; }; -type AgeDataType = { +export type AgeDataType = { value: number | null; - birthyear: string; + birthyear: string | null; title: string; description: string; bar: BarType; @@ -40,14 +40,7 @@ interface VaccineCoverageTileProps { dateUnix: number; } -export const VaccineCoverageTile = ({ - title, - description, - source, - descriptionFooter, - dateUnix, - coverageData, -}: VaccineCoverageTileProps) => { +export const VaccineCoverageTile = ({ title, description, source, descriptionFooter, dateUnix, coverageData }: VaccineCoverageTileProps) => { const metadata: MetadataProps = { date: dateUnix, source: source, @@ -84,16 +77,11 @@ interface AgeGroupBlockProps { const AgeGroupBlock = ({ data, bar, children }: AgeGroupBlockProps) => { const { commonTexts, formatPercentage } = useIntl(); - const parsedAgePercentage = data.value - ? `${formatPercentage(data.value)}%` - : '-'; + const parsedAgePercentage = data.value ? `${formatPercentage(data.value)}%` : '-'; - const parsedBirthyearRange = parseBirthyearRange(data.birthyear); + const parsedBirthyearRange = data.birthyear ? parseBirthyearRange(data.birthyear) : null; - assert( - parsedBirthyearRange, - `[${AgeGroupBlock.name}] Something went wrong with parsing the birthyear: ${data.birthyear}` - ); + assert(parsedBirthyearRange, `[${AgeGroupBlock.name}] Something went wrong with parsing the birthyear: ${data.birthyear}`); return ( @@ -106,10 +94,7 @@ const AgeGroupBlock = ({ data, bar, children }: AgeGroupBlockProps) => { {children} diff --git a/packages/app/src/pages/gemeente/[code]/vaccinaties.tsx b/packages/app/src/pages/gemeente/[code]/vaccinaties.tsx index 0ad79b5b84..d92fd82f21 100644 --- a/packages/app/src/pages/gemeente/[code]/vaccinaties.tsx +++ b/packages/app/src/pages/gemeente/[code]/vaccinaties.tsx @@ -1,20 +1,14 @@ import { colors, GmCollectionVaccineCoveragePerAgeGroup } from '@corona-dashboard/common'; -import css from '@styled-system/css'; import { Vaccinaties as VaccinatieIcon } from '@corona-dashboard/icons'; import { GetStaticPropsContext } from 'next'; import { useState } from 'react'; -import { hasValueAtKey, isDefined, isPresent } from 'ts-is-present'; -import { Box } from '~/components/base'; -import { DynamicChoropleth, ChoroplethTile, Markdown, PageInformationBlock, TileList, Divider } from '~/components'; -import { thresholds } from '~/components/choropleth/logic'; +import { isDefined, isPresent } from 'ts-is-present'; +import { PageInformationBlock, TileList, Divider } from '~/components'; import { gmCodesByVrCode, vrCodeByGmCode } from '~/data'; import { Layout, GmLayout } from '~/domain/layout'; import { Languages, SiteText } from '~/locale'; -import { BoldText } from '~/components/typography'; -import { matchingAgeGroups } from '~/domain/vaccine/common'; -import { AgeGroup, AgeGroupSelect } from '~/domain/vaccine/components/age-group-select'; -import { VaccinationCoverageKindSelect, CoverageKindProperty } from '~/domain/vaccine/components/vaccination-coverage-kind-select'; -import { selectVaccineCoverageData, VaccineCoverageToggleTile, ChoroplethTooltip, VaccineCoveragePerAgeGroup, VaccineCoverageTile } from '~/domain/vaccine'; +import { VaccineCoverageToggleTile, VaccineCoveragePerAgeGroup, VaccineCoverageTile } from '~/domain/vaccine'; +import { AgeDataType } from '~/domain/vaccine/vaccine-coverage-tile/vaccine-coverage-tile'; import { useIntl } from '~/intl'; import { getArticleParts, getLinkParts, getPagePartsQuery } from '~/queries/get-page-parts-query'; import { createGetStaticProps, StaticProps } from '~/static-props/create-get-static-props'; @@ -23,6 +17,7 @@ import { ArticleParts, LinkParts, PagePartQueryResult } from '~/types/cms'; import { assert, replaceVariablesInText, useReverseRouter, useFormatLokalizePercentage } from '~/utils'; import { getLastInsertionDateOfPage } from '~/utils/get-last-insertion-date-of-page'; import { useDynamicLokalizeTexts } from '~/utils/cms/use-dynamic-lokalize-texts'; +import { VaccineCoverageChoroplethVrAndGm } from '~/domain/vaccine/vaccine-coverage-choropleth_vr_and_gm'; const pageMetrics = ['vaccine_coverage_per_age_group', 'vaccine_coverage_per_age_group_archived', 'booster_coverage_archived_20220904']; @@ -34,6 +29,11 @@ const selectLokalizeTexts = (siteText: SiteText) => ({ type LokalizeTexts = ReturnType; +type ParsedCoverageData = { + autumn2022: [AgeDataType, AgeDataType]; + primarySeries: [AgeDataType, AgeDataType]; +}; + export { getStaticPaths } from '~/static-paths/gm'; export const getStaticProps = createGetStaticProps( @@ -56,9 +56,9 @@ export const getStaticProps = createGetStaticProps( const vrCode = isPresent(ctx.params?.code) ? vrCodeByGmCode[ctx.params?.code as 'string'] : undefined; return { - vaccine_coverage_per_age_group: selectVaccineCoverageData( - isDefined(vrCode) ? vaccine_coverage_per_age_group.filter((el) => gmCodesByVrCode[vrCode].includes(el.gmcode)) : vaccine_coverage_per_age_group - ), + vaccine_coverage_per_age_group: isDefined(vrCode) + ? vaccine_coverage_per_age_group.filter((vaccineCoveragePerAgeGroup) => gmCodesByVrCode[vrCode].includes(vaccineCoveragePerAgeGroup.gmcode)) + : vaccine_coverage_per_age_group, }; }, }), @@ -77,11 +77,9 @@ export const getStaticProps = createGetStaticProps( export const VaccinationsGmPage = (props: StaticProps) => { const { pageText, choropleth, municipalityName, selectedGmData: data, content, lastGenerated } = props; const { commonTexts } = useIntl(); - const reverseRouter = useReverseRouter(); - const [selectedAgeGroup, setSelectedAgeGroup] = useState('18+'); - const [selectedCoverageKind, setSelectedCoverageKind] = useState('fully_vaccinated_percentage'); const { formatPercentageAsNumber } = useFormatLokalizePercentage(); const [hasHideArchivedCharts, setHideArchivedCharts] = useState(false); + const reverseRouter = useReverseRouter(); const { textGm, textNl, textShared } = useDynamicLokalizeTexts(pageText, selectLokalizeTexts); @@ -95,49 +93,71 @@ export const VaccinationsGmPage = (props: StaticProps) => }), }; - /** - * When changing between coverage kinds where the selected age group isn't available, - * the other coverage kind set the non-matching age group to a default one. - */ - const setSelectedCoverageKindAndAge = (coverageKind: CoverageKindProperty) => { - if (coverageKind === selectedCoverageKind) return; - if (selectedAgeGroup !== '12+') { - setSelectedAgeGroup(selectedAgeGroup === '18+' ? '60+' : '18+'); - } - setSelectedCoverageKind(coverageKind); + const filteredVaccination = { + primarySeries: data.vaccine_coverage_per_age_group.values.find((item) => item.vaccination_type === 'primary_series'), + autumn2022: data.vaccine_coverage_per_age_group.values.find((item) => item.vaccination_type === 'autumn_2022'), }; - /** - * Filter out only the the 12+ and 18+ for the toggle component. - */ - const filteredAgeGroup60Plus = data.vaccine_coverage_per_age_group.values.find((x) => x.age_group_range === '60+'); - - const filteredAgeGroup18Plus = data.vaccine_coverage_per_age_group.values.find((x) => x.age_group_range === '18+'); - - const filteredAgeGroup12Plus = data.vaccine_coverage_per_age_group.values.find((x) => x.age_group_range === '12+'); - - /** - * Archived - Filter out only the the 12+ and 18+ for the toggle component. - */ - const filteredArchivedAgeGroup18Plus = data.vaccine_coverage_per_age_group_archived_20220908.values.find((x) => x.age_group_range === '18+'); - - const filteredArchivedAgeGroup12Plus = data.vaccine_coverage_per_age_group_archived_20220908.values.find((x) => x.age_group_range === '12+'); + assert(filteredVaccination.primarySeries, `[${VaccinationsGmPage.name}] Could not find data for the vaccine coverage per age group for the primary series`); + assert(filteredVaccination.autumn2022, `[${VaccinationsGmPage.name}] Could not find data for the vaccine coverage per age group for the autumn 2022 series`); const boosterCoverage18PlusArchivedValue = data.booster_coverage_archived_20220904?.values?.find((v) => v.age_group === '18+'); const boosterCoverage12PlusArchivedValue = data.booster_coverage_archived_20220904?.values?.find((v) => v.age_group === '12+'); - assert(filteredAgeGroup60Plus, `[${VaccinationsGmPage.name}] Could not find data for the vaccine coverage per age group for the age 60+`); - - assert(filteredAgeGroup18Plus, `[${VaccinationsGmPage.name}] Could not find data for the vaccine coverage per age group for the age 18+`); - - assert(filteredAgeGroup12Plus, `[${VaccinationsGmPage.name}] Could not find data for the vaccine coverage per age group for the age 12+`); + const filteredArchivedAgeGroup18Plus = data.vaccine_coverage_per_age_group_archived_20220908.values.find((x) => x.age_group_range === '18+'); + const filteredArchivedAgeGroup12Plus = data.vaccine_coverage_per_age_group_archived_20220908.values.find((x) => x.age_group_range === '12+'); assert(filteredArchivedAgeGroup18Plus, `[${VaccinationsGmPage.name}] Could not find data for the archived vaccine coverage per age group for the age 18+`); - assert(filteredArchivedAgeGroup12Plus, `[${VaccinationsGmPage.name}] Could not find data for the archived vaccine coverage per age group for the age 12+`); const lastInsertionDateOfPage = getLastInsertionDateOfPage(data, pageMetrics); - const choroplethData: GmCollectionVaccineCoveragePerAgeGroup[] = choropleth.gm.vaccine_coverage_per_age_group.filter(hasValueAtKey('age_group_range', selectedAgeGroup)); + + const parsedVaccineCoverageData: ParsedCoverageData = { + autumn2022: [ + { + value: filteredVaccination.autumn2022.vaccinated_percentage_60_plus, + birthyear: filteredVaccination.autumn2022.birthyear_range_60_plus, + title: textShared.vaccination_grade_tile.age_group_labels.age_60_plus, + description: textShared.vaccination_grade_tile.autumn_labels.description_60_plus, + bar: { + value: filteredVaccination.autumn2022.vaccinated_percentage_60_plus || 0, + color: colors.scale.blueDetailed[8], + }, + }, + { + value: filteredVaccination.autumn2022.vaccinated_percentage_12_plus, + birthyear: filteredVaccination.autumn2022.birthyear_range_12_plus, + title: textShared.vaccination_grade_tile.age_group_labels.age_12_plus, + description: textShared.vaccination_grade_tile.autumn_labels.description_12_plus, + bar: { + value: filteredVaccination.autumn2022.vaccinated_percentage_12_plus || 0, + color: colors.scale.blueDetailed[8], + }, + }, + ], + primarySeries: [ + { + value: filteredVaccination.primarySeries.vaccinated_percentage_18_plus, + birthyear: filteredVaccination.primarySeries.birthyear_range_18_plus, + title: textShared.vaccination_grade_tile.age_group_labels.age_18_plus, + description: textShared.vaccination_grade_tile.fully_vaccinated_labels.description_18_plus, + bar: { + value: filteredVaccination.primarySeries.vaccinated_percentage_18_plus || 0, + color: colors.scale.blueDetailed[3], + }, + }, + { + value: filteredVaccination.primarySeries.vaccinated_percentage_12_plus, + birthyear: filteredVaccination.primarySeries.birthyear_range_12_plus, + title: textShared.vaccination_grade_tile.age_group_labels.age_12_plus, + description: textShared.vaccination_grade_tile.fully_vaccinated_labels.description_12_plus, + bar: { + value: filteredVaccination.primarySeries.vaccinated_percentage_12_plus || 0, + color: colors.scale.blueDetailed[3], + }, + }, + ], + }; return ( @@ -152,7 +172,7 @@ export const VaccinationsGmPage = (props: StaticProps) => icon={