From 4cf50b4a5effb6baf928f393182ecd317a237d13 Mon Sep 17 00:00:00 2001 From: VWSCoronaDashboard28 Date: Wed, 13 Sep 2023 16:15:19 +0200 Subject: [PATCH 01/12] feat(contact-page-redesign): Updated and added the neccessary schemas for the new design. --- .../src/schemas/documents/pages/contact.ts | 28 ------- .../schemas/documents/pages/contact/group.ts | 30 ++++++++ .../schemas/documents/pages/contact/index.ts | 30 ++++++++ .../schemas/documents/pages/contact/item.ts | 73 +++++++++++++++++++ .../schemas/documents/pages/contact/link.ts | 36 +++++++++ packages/cms/src/schemas/index.ts | 11 ++- packages/cms/src/schemas/objects/link-type.ts | 23 ++++++ 7 files changed, 201 insertions(+), 30 deletions(-) delete mode 100644 packages/cms/src/schemas/documents/pages/contact.ts create mode 100644 packages/cms/src/schemas/documents/pages/contact/group.ts create mode 100644 packages/cms/src/schemas/documents/pages/contact/index.ts create mode 100644 packages/cms/src/schemas/documents/pages/contact/item.ts create mode 100644 packages/cms/src/schemas/documents/pages/contact/link.ts create mode 100644 packages/cms/src/schemas/objects/link-type.ts diff --git a/packages/cms/src/schemas/documents/pages/contact.ts b/packages/cms/src/schemas/documents/pages/contact.ts deleted file mode 100644 index 7f88393b98..0000000000 --- a/packages/cms/src/schemas/documents/pages/contact.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { localeStringValidation, localeValidation } from '../../../studio/validation/locale-validation'; -import { defineField, defineType } from 'sanity'; - -export const contact = defineType({ - name: 'contact', - type: 'document', - title: 'Contact', - fields: [ - defineField({ - name: 'title', - type: 'localeString', - title: 'Titel', - validation: localeStringValidation((rule) => rule.required()), - }), - defineField({ - name: 'description', - type: 'localeBlock', - title: 'Beschrijving', - validation: localeValidation((rule) => rule.required()), - }), - ], - preview: { - select: { - title: 'title.nl', - subtitle: 'description.nl', - }, - }, -}); diff --git a/packages/cms/src/schemas/documents/pages/contact/group.ts b/packages/cms/src/schemas/documents/pages/contact/group.ts new file mode 100644 index 0000000000..04c92a4df5 --- /dev/null +++ b/packages/cms/src/schemas/documents/pages/contact/group.ts @@ -0,0 +1,30 @@ +import { defineArrayMember, defineField, defineType } from 'sanity'; +import { localeStringValidation } from '../../../../studio/validation/locale-validation'; + +export const contactPageGroup = defineType({ + name: 'contactPageGroup', + title: 'Contactpaginagroep', + description: 'Configureer een groep voor de contactpagina. Stel de titel voor een groep in en voeg er items aan toe.', + type: 'document', + fields: [ + defineField({ + name: 'title', + title: 'Groepstitel', + type: 'localeString', + description: 'Configureer de titel voor deze groep.', + validation: localeStringValidation((rule) => rule.required()), + }), + defineField({ + name: 'contactPageGroupItems', + title: 'Groep Items', + type: 'array', + description: 'Voeg items toe aan deze groep.', + of: [defineArrayMember({ type: 'reference', to: { type: 'contactPageGroupItem' } })], + }), + ], + preview: { + select: { + title: 'title.nl', + }, + }, +}); diff --git a/packages/cms/src/schemas/documents/pages/contact/index.ts b/packages/cms/src/schemas/documents/pages/contact/index.ts new file mode 100644 index 0000000000..5525370bb9 --- /dev/null +++ b/packages/cms/src/schemas/documents/pages/contact/index.ts @@ -0,0 +1,30 @@ +import { defineArrayMember, defineField, defineType } from 'sanity'; + +export const contact = defineType({ + name: 'contact', + title: 'Contact Page', + description: + 'Dit is het startpunt voor het configureren van de contactpagina. Stel een optionele titel voor de pagina in en voeg er secties aan toe met behulp van de onderstaande lijst.', + type: 'document', + fields: [ + defineField({ + name: 'title', + title: 'Pagina Titel', + description: 'Configureer de titel voor de contactpagina. Het is niet verplicht dit veld in te vullen.', + type: 'localeString', + }), + defineField({ + name: 'contactPageGroups', + title: 'Pagina Groepen', + description: 'Groepen toevoegen, verwijderen of opnieuw rangschikken op de contactpagina.', + type: 'array', + of: [defineArrayMember({ type: 'reference', to: { type: 'contactPageGroup' } })], + validation: (rule) => rule.required().min(3).error('De contactpagina moet minimaal 3 secties bevatten.'), + }), + ], + preview: { + select: { + title: 'title.nl', + }, + }, +}); diff --git a/packages/cms/src/schemas/documents/pages/contact/item.ts b/packages/cms/src/schemas/documents/pages/contact/item.ts new file mode 100644 index 0000000000..b7660e3e62 --- /dev/null +++ b/packages/cms/src/schemas/documents/pages/contact/item.ts @@ -0,0 +1,73 @@ +import { defineArrayMember, defineField, defineType } from 'sanity'; +import { localeValidation } from '../../../../studio/validation/locale-validation'; + +export const contactPageGroupItem = defineType({ + name: 'contactPageGroupItem', + title: 'Contactpagina Item', + description: 'Configureer een item voor een bepaalde contactpaginagroep.', + type: 'document', + fieldsets: [ + { + title: 'Item Titel Configuratie', + name: 'titleConfiguration', + options: { + collapsible: true, + collapsed: false, + }, + }, + { + title: 'Item Beschrijving', + name: 'itemDescription', + options: { + collapsible: true, + collapsed: false, + }, + }, + ], + fields: [ + defineField({ + name: 'title', + title: 'Titel', + description: + 'Configureer de titel en de link voor dit item. Als u een link aan een e-mail wilt toevoegen, vult u alleen het e-mailadres in. Als je een link naar een telefoonnummer wilt toevoegen, voeg dan alleen het nummer toe.', + type: 'localeString', + fieldset: 'titleConfiguration', + validation: (rule) => rule.required(), + }), + defineField({ + name: 'itemTitleUrl', + title: 'Link', + description: + 'De bestemming voor de link naar de itemtitel. U kunt dit veld leeg laten als de titel geen link vereist. Als u een link aan een e-mail wilt toevoegen, vult u alleen het e-mailadres in. Als je een link naar een telefoonnummer wilt toevoegen, voeg dan alleen het nummer toe.', + type: 'string', + fieldset: 'titleConfiguration', + }), + defineField({ + name: 'linkType', + type: 'linkType', + fieldset: 'titleConfiguration', + validation: (rule) => rule.required(), + }), + defineField({ + name: 'description', + title: 'Beschrijving', + description: 'Configureer een beschrijving. Wordt onder de titel getoond.', + type: 'localeBlock', + fieldset: 'itemDescription', + validation: localeValidation((rule) => rule.required()), + }), + defineField({ + name: 'contactPageItemLinks', + title: 'Item Links', + description: 'Configureer een lijst met links voor dit item. Als er geen links nodig zijn, kan deze leeg gelaten worden. Deze worden onder de beschrijving weergegeven.', + type: 'array', + of: [defineArrayMember({ type: 'contactPageItemLink' })], + }), + ], + preview: { + select: { + title: 'title.nl', + subtitle: 'description.nl', + }, + }, +}); diff --git a/packages/cms/src/schemas/documents/pages/contact/link.ts b/packages/cms/src/schemas/documents/pages/contact/link.ts new file mode 100644 index 0000000000..8ff6209e5d --- /dev/null +++ b/packages/cms/src/schemas/documents/pages/contact/link.ts @@ -0,0 +1,36 @@ +import { defineField, defineType } from 'sanity'; + +export const contactPageItemLink = defineType({ + name: 'contactPageItemLink', + title: 'Contactpagina Itemlink', + description: + 'Configureer een link voor een bepaald pagina-item. Kies het linktype en voeg een label toe. Als u een link aan een e-mail wilt toevoegen, vult u alleen het e-mailadres in. Als je een link naar een telefoonnummer wilt toevoegen, voeg dan alleen het nummer toe.', + type: 'document', + fields: [ + defineField({ + name: 'link', + title: 'Link', + description: + "Configureer de link en het bijbehorende label. Als de link een telefoonnummer is, vermijd dan het gebruik van spaties. Als het een internationaal nummer is, vervang dan '+' door '00'.", + type: 'link', + validation: (rule) => rule.required(), + }), + defineField({ + name: 'linkType', + type: 'linkType', + validation: (rule) => rule.required(), + }), + defineField({ + name: 'title', + title: 'Link Titel', + description: 'Configureer indien nodig een titel die boven de link wordt weergegeven. Dit is niet het linklabel. Gebruik dit alleen als het linklabel niet voldoende is.', + type: 'localeString', + }), + ], + preview: { + select: { + title: 'link.title.nl', + subtitle: 'link.href', + }, + }, +}); diff --git a/packages/cms/src/schemas/index.ts b/packages/cms/src/schemas/index.ts index 3cff87000c..e34dd3613c 100644 --- a/packages/cms/src/schemas/index.ts +++ b/packages/cms/src/schemas/index.ts @@ -9,6 +9,9 @@ import { links } from './documents/page-parts/links'; import { about } from './documents/pages/about'; import { accessibility } from './documents/pages/accessibility'; import { contact } from './documents/pages/contact'; +import { contactPageGroup } from './documents/pages/contact/group'; +import { contactPageGroupItem } from './documents/pages/contact/item'; +import { contactPageItemLink } from './documents/pages/contact/link'; import { dataExplained } from './documents/pages/data-explained'; import { dataExplainedGroups } from './documents/pages/data-explained/groups'; import { dataExplainedItem } from './documents/pages/data-explained/item'; @@ -37,19 +40,23 @@ import { timeSeries } from './elements/time-series'; import { timelineEvent } from './elements/timeline-event'; import { timelineEventCollection } from './elements/timeline-event-collection'; import { block } from './locale/block'; +import { image } from './locale/image'; import { richContentBlock } from './locale/rich-content-block'; import { string } from './locale/string'; import { text } from './locale/text'; -import { image } from './locale/image'; import { inlineBlock } from './objects/inline-block'; import { inlineCollapsible } from './objects/inline-collapsible'; import { link } from './objects/link'; +import { linkType } from './objects/link-type'; const localeSpecificSchemas = [block, richContentBlock, string, text, image]; const richContentSchemas = [inlineBlock, inlineCollapsible]; const documentSchemas = [ advice, article, + contactPageGroup, + contactPageGroupItem, + contactPageItemLink, dataExplainedGroups, dataExplainedItem, faqGroups, @@ -75,6 +82,6 @@ const documentSchemas = [ const pageSchemas = [about, accessibility, contact, dataExplained, faq, homepage, notFound]; const pagePartSchemas = [articles, dataExplainedParts, faqParts, highlights, links]; const elementSchemas = [timelineEvent, timelineEventCollection, timeSeries]; -const objectSchemas = [link]; +const objectSchemas = [link, linkType]; export const schemaTypes = [...localeSpecificSchemas, ...richContentSchemas, ...documentSchemas, ...elementSchemas, ...pageSchemas, ...pagePartSchemas, ...objectSchemas]; diff --git a/packages/cms/src/schemas/objects/link-type.ts b/packages/cms/src/schemas/objects/link-type.ts new file mode 100644 index 0000000000..18335e681d --- /dev/null +++ b/packages/cms/src/schemas/objects/link-type.ts @@ -0,0 +1,23 @@ +import { defineField, defineType } from 'sanity'; + +export const linkType = defineType({ + name: 'linkType', + title: 'Linktype', + type: 'object', + fields: [ + defineField({ + name: 'linkType', + title: 'Linktype', + description: 'Selecteer het type link op basis van of het een e-mail, telefoon of normaal link is.', + type: 'string', + options: { + list: [ + { value: 'regular', title: 'Normaal' }, + { value: 'email', title: 'E-mail' }, + { value: 'phone', title: 'Telefoon' }, + ], + layout: 'dropdown', + }, + }), + ], +}); From 9f8fd9bf65ecd2364f60e2440d26492577ed4ef4 Mon Sep 17 00:00:00 2001 From: VWSCoronaDashboard28 Date: Thu, 14 Sep 2023 13:12:43 +0200 Subject: [PATCH 02/12] feat(contact-page-redesign): Updated validation for the link and link type of an items title. Also added some UX improvements to hide the field unless it needs to be filled. --- packages/cms/src/schemas/documents/pages/contact/item.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/cms/src/schemas/documents/pages/contact/item.ts b/packages/cms/src/schemas/documents/pages/contact/item.ts index b7660e3e62..7b3cafba48 100644 --- a/packages/cms/src/schemas/documents/pages/contact/item.ts +++ b/packages/cms/src/schemas/documents/pages/contact/item.ts @@ -1,4 +1,4 @@ -import { defineArrayMember, defineField, defineType } from 'sanity'; +import { ValidationContext, defineArrayMember, defineField, defineType } from 'sanity'; import { localeValidation } from '../../../../studio/validation/locale-validation'; export const contactPageGroupItem = defineType({ @@ -46,7 +46,12 @@ export const contactPageGroupItem = defineType({ name: 'linkType', type: 'linkType', fieldset: 'titleConfiguration', - validation: (rule) => rule.required(), + validation: (rule) => + rule.custom((value, context: ValidationContext) => { + const parent = context.parent as { itemTitleUrl: string }; + return 'itemTitleUrl' in parent && parent.itemTitleUrl.length && value === undefined ? 'Dit veld is verplicht als uw titel een link bevat' : true; + }), + hidden: ({ parent }) => !('itemTitleUrl' in parent && parent.itemTitleUrl.length), }), defineField({ name: 'description', From 0b868325938d760f6fb0dc9e94a530f2dfd22f69 Mon Sep 17 00:00:00 2001 From: VWSCoronaDashboard28 Date: Thu, 14 Sep 2023 17:51:36 +0200 Subject: [PATCH 03/12] feat(contact-page-redesign): Added a telephone Icon. --- packages/icons/icons.md | 1 + packages/icons/src/icon-name2filename.ts | 2 ++ packages/icons/src/svg/telephone.svg | 1 + 3 files changed, 4 insertions(+) create mode 100644 packages/icons/src/svg/telephone.svg diff --git a/packages/icons/icons.md b/packages/icons/icons.md index f25d8423a3..b791afa664 100644 --- a/packages/icons/icons.md +++ b/packages/icons/icons.md @@ -120,6 +120,7 @@ See below an overview of all the available icons in this package. This file is g | Stap1WinkelsOpen |
Stap1WinkelsOpen
| | Stopwatch |
Stopwatch
| | Taxi |
Taxi
| +| Telephone |
Telephone
| | Testbewijs |
Testbewijs
| | Toegangsbewijzen |
Toegangsbewijzen
| | Town |
Town
| diff --git a/packages/icons/src/icon-name2filename.ts b/packages/icons/src/icon-name2filename.ts index 5474596caa..307f71583c 100644 --- a/packages/icons/src/icon-name2filename.ts +++ b/packages/icons/src/icon-name2filename.ts @@ -115,6 +115,7 @@ export type IconName = | 'Stap1WinkelsOpen' | 'Stopwatch' | 'Taxi' + | 'Telephone' | 'Testbewijs' | 'Toegangsbewijzen' | 'Town' @@ -254,6 +255,7 @@ export const iconName2filename: Record = { Stap1WinkelsOpen: 'stap_1_winkels_open.svg', Stopwatch: 'stopwatch.svg', Taxi: 'taxi.svg', + Telephone: 'telephone.svg', Testbewijs: 'testbewijs.svg', Toegangsbewijzen: 'toegangsbewijzen.svg', Town: 'town.svg', diff --git a/packages/icons/src/svg/telephone.svg b/packages/icons/src/svg/telephone.svg new file mode 100644 index 0000000000..5048827c1f --- /dev/null +++ b/packages/icons/src/svg/telephone.svg @@ -0,0 +1 @@ + \ No newline at end of file From 99770cbde8acd1ac7489357394c1a1876a0ac808 Mon Sep 17 00:00:00 2001 From: VWSCoronaDashboard28 Date: Thu, 14 Sep 2023 17:52:06 +0200 Subject: [PATCH 04/12] feat(contact-page-redesign): Upated group schema with validation --- packages/cms/src/schemas/documents/pages/contact/group.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/cms/src/schemas/documents/pages/contact/group.ts b/packages/cms/src/schemas/documents/pages/contact/group.ts index 04c92a4df5..b73ccaa498 100644 --- a/packages/cms/src/schemas/documents/pages/contact/group.ts +++ b/packages/cms/src/schemas/documents/pages/contact/group.ts @@ -20,6 +20,7 @@ export const contactPageGroup = defineType({ type: 'array', description: 'Voeg items toe aan deze groep.', of: [defineArrayMember({ type: 'reference', to: { type: 'contactPageGroupItem' } })], + validation: (rule) => rule.required(), }), ], preview: { From 0f9549ebcb3d84d71bf9f43211634d23592ecc81 Mon Sep 17 00:00:00 2001 From: VWSCoronaDashboard28 Date: Thu, 14 Sep 2023 18:03:40 +0200 Subject: [PATCH 05/12] feat(contact-page-redesign): Contact page redesign WIP --- packages/app/src/pages/contact.tsx | 252 +++++++++++++++++++++++------ 1 file changed, 199 insertions(+), 53 deletions(-) diff --git a/packages/app/src/pages/contact.tsx b/packages/app/src/pages/contact.tsx index 287d60eb6c..c5ca36649f 100644 --- a/packages/app/src/pages/contact.tsx +++ b/packages/app/src/pages/contact.tsx @@ -1,86 +1,232 @@ -import css from '@styled-system/css'; +import { colors } from '@corona-dashboard/common'; +import { ChevronRight, External, Telephone } from '@corona-dashboard/icons'; import Head from 'next/head'; import styled from 'styled-components'; +import { Box } from '~/components/base/box'; import { RichContent } from '~/components/cms/rich-content'; +import { ExternalLink } from '~/components/external-link'; import { Heading } from '~/components/typography'; -import { Content } from '~/domain/layout/content'; import { Layout } from '~/domain/layout/layout'; import { useIntl } from '~/intl'; -import { - createGetStaticProps, - StaticProps, -} from '~/static-props/create-get-static-props'; -import { - createGetContent, - getLastGeneratedDate, -} from '~/static-props/get-data'; +import { StaticProps, createGetStaticProps } from '~/static-props/create-get-static-props'; +import { createGetContent, getLastGeneratedDate } from '~/static-props/get-data'; +import { radii, sizes, space } from '~/style/theme'; import { RichContentBlock } from '~/types/cms'; +import { isInternalUrl } from '~/utils/is-internal-url'; +import { Link } from '~/utils/link'; + +type LinkType = 'regular' | 'email' | 'phone'; -interface ContactData { - title: string | null; - description: RichContentBlock[] | null; +interface ItemLink { + id: string; + linkHref: string; + linkLabel: string; + linkType: LinkType; + titleAboveLink?: string; +} +interface GroupItem { + description: RichContentBlock[]; + id: string; + itemTitle: string; + itemLinks?: ItemLink[]; + itemTitleUrl?: string; + linkType?: LinkType; +} + +interface PageGroups { + id: string; + groupTitle: string; + groupItems: GroupItem[]; +} +interface ContactPage { + pageGroups: PageGroups[]; + pageTitle?: string | null; } export const getStaticProps = createGetStaticProps( getLastGeneratedDate, - createGetContent((context) => { + createGetContent((context) => { const { locale } = context; - return `*[_type == 'contact']{ - title, - "description": { - "_type": description._type, - "${locale}": [ - ...description.${locale}[] - { - ..., - "asset": asset-> - }, - ] + return `*[_type == 'contact'] { + 'pageTitle': title.${locale}, + 'pageGroups': contactPageGroups[]->{ + 'id': _id, + 'groupTitle': title.${locale}, + 'groupItems': contactPageGroupItems[]->{ + 'id': _id, + 'itemTitle': title.${locale}, + 'itemTitleUrl': itemTitleUrl, + 'linkType': linkType.linkType, + 'description': description.${locale}, + 'itemLinks': contactPageItemLinks[]{ + 'id': _id, + 'titleAboveLink': title.${locale}, + 'linkType': linkType.linkType, + 'linkLabel': link.title.${locale}, + 'linkHref': link.href + } + } } - }[0] - `; + }[0]`; }) ); +const formatLinkAccordingToType = (href: string, linkType: LinkType | undefined) => { + switch (linkType) { + case 'email': + return `mailto:${href}`; + case 'phone': + return `tel:${href.replace(/\s/g, '').replace('-', '')}`; + default: + return href; + } +}; + +const renderLinkWithIcon = (href: string, linkText: string, linkType: LinkType | undefined) => { + if (isInternalUrl(href)) { + return ( + + + + {linkText} + + + + + ); + } + + return ( + + + {linkType === 'phone' && } + {linkText} + {linkType !== 'phone' && } + + + ); +}; + const Contact = (props: StaticProps) => { const { commonTexts } = useIntl(); - const { content, lastGenerated } = props; + const { + content: { pageTitle, pageGroups }, + lastGenerated, + } = props; return ( - - + + - - {content.title && {content.title}} - {content.description && ( - + {/* The dimensions of this box are duplicated on the FAQ and about page, abstract if possible */} + + {pageTitle && ( + + {pageTitle} + )} - + + { + // Consider using some unique ID instead of index + pageGroups.map((group) => { + const { id, groupTitle, groupItems } = group; + return ( + + + {groupTitle} + + + {groupItems.map((item, index) => { + const { id, itemTitle, itemTitleUrl, linkType, description, itemLinks } = item; + + return ( + + + {itemTitleUrl ? {renderLinkWithIcon(itemTitleUrl, itemTitle, linkType)} : {itemTitle}} + + + + + {itemLinks && } + + ); + })} + + ); + }) + } + ); }; -const RichContentWrapper = styled.div( - css({ - maxWidth: 'maxWidthText', - width: '100%', - }) -); +interface LinkWrapperProps { + iconMargin: string; +} + +const LinkWrapper = styled.div` + a { + align-items: center; + display: flex; + } + + svg { + height: 16px; + margin: ${({ iconMargin }) => iconMargin}; + width: 16px; + } +`; + +const LinkListItem = styled.div` + border-radius: ${radii[1]}px; + border: 1px solid ${colors.gray3}; + display: inline-block; + padding: ${space[2]} ${space[3]}; + transition: all 0.2s; + + &:hover { + background-color: ${colors.blue8}; + + a { + color: ${colors.white}; + } + } +`; + +const RichContentWrapper = styled.div` + width: 100%; +`; + +interface ContactPageItemLinksProps { + links: ItemLink[]; +} + +const ContactPageItemLinks = ({ links }: ContactPageItemLinksProps) => { + return ( + + {links.map(({ id, titleAboveLink, linkHref, linkLabel, linkType }) => ( + + {titleAboveLink && ( + + {titleAboveLink} + + )} + + {renderLinkWithIcon(linkHref, linkLabel, linkType)} + + ))} + + ); +}; export default Contact; From a1347ed57e7fa10162a7d9e12ab6cccf78ea0550 Mon Sep 17 00:00:00 2001 From: VWSCoronaDashboard28 Date: Mon, 18 Sep 2023 13:28:02 +0200 Subject: [PATCH 06/12] feat(contact-page-redesign): Extended the heading component so it can accept margins. --- packages/app/src/components/typography.tsx | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/app/src/components/typography.tsx b/packages/app/src/components/typography.tsx index e4e31c3069..bf0048d955 100644 --- a/packages/app/src/components/typography.tsx +++ b/packages/app/src/components/typography.tsx @@ -3,7 +3,14 @@ import css, { CSSProperties } from '@styled-system/css'; import styled, { DefaultTheme } from 'styled-components'; import { Preset, preset } from '~/style/preset'; -export interface TextProps { +interface AllMarginProps { + margin?: CSSProperties['margin']; + marginRight?: CSSProperties['marginRight']; + marginBottom?: CSSProperties['marginBottom']; + marginLeft?: CSSProperties['marginLeft']; +} + +export interface TextProps extends AllMarginProps { variant?: keyof Preset['typography']; fontWeight?: keyof DefaultTheme['fontWeights']; textTransform?: CSSProperties['textTransform']; @@ -32,6 +39,10 @@ export const textStyle = (props: TextProps & { as?: string }) => { ...(props.textTransform ? { textTransform: props.textTransform } : undefined), ...(props.textAlign ? { textAlign: props.textAlign } : undefined), ...(props.hyphens ? { hyphens: props.hyphens } : undefined), + ...(props.margin ? { margin: props.margin } : undefined), + ...(props.marginRight ? { marginRight: props.marginRight } : undefined), + ...(props.marginBottom ? { marginBottom: props.marginBottom } : undefined), + ...(props.marginLeft ? { marginLeft: props.marginLeft } : undefined), }); }; From b0ebd125cf0b9861333452611424bf96b629cb68 Mon Sep 17 00:00:00 2001 From: VWSCoronaDashboard28 Date: Mon, 18 Sep 2023 13:29:22 +0200 Subject: [PATCH 07/12] feat(contact-page-redesign): Refactoring. --- packages/app/src/components/contact/item.tsx | 35 +++ packages/app/src/components/contact/links.tsx | 45 ++++ packages/app/src/components/contact/types.ts | 32 +++ packages/app/src/pages/contact.tsx | 210 +++--------------- 4 files changed, 141 insertions(+), 181 deletions(-) create mode 100644 packages/app/src/components/contact/item.tsx create mode 100644 packages/app/src/components/contact/links.tsx create mode 100644 packages/app/src/components/contact/types.ts diff --git a/packages/app/src/components/contact/item.tsx b/packages/app/src/components/contact/item.tsx new file mode 100644 index 0000000000..73eb621a4a --- /dev/null +++ b/packages/app/src/components/contact/item.tsx @@ -0,0 +1,35 @@ +import { colors } from '@corona-dashboard/common'; +import { radii, space } from '~/style/theme'; +import { Box } from '../base/box'; +import { RichContent } from '../cms/rich-content'; +import { Heading } from '../typography'; +import styled from 'styled-components'; +import { GroupItem } from './types'; +import { renderLinkWithIcon } from './logic'; +import { ContactPageItemLinks } from './links'; + +interface ContactPageGroupItemProps { + groupItemsLength: number; + index: number; + item: GroupItem; +} + +export const ContactPageGroupItem = ({ item, index, groupItemsLength }: ContactPageGroupItemProps) => { + const { title, titleUrl, linkType, description, links } = item; + + return ( + + + {titleUrl ? renderLinkWithIcon(titleUrl, title, linkType) : title} + + + + + {links && } + + ); +}; + +const RichContentWrapper = styled.div` + width: 100%; +`; diff --git a/packages/app/src/components/contact/links.tsx b/packages/app/src/components/contact/links.tsx new file mode 100644 index 0000000000..a82ee5a213 --- /dev/null +++ b/packages/app/src/components/contact/links.tsx @@ -0,0 +1,45 @@ +import { colors } from '@corona-dashboard/common'; +import styled from 'styled-components'; +import { radii, space } from '~/style/theme'; +import { Box } from '../base/box'; +import { Heading } from '../typography'; +import { renderLinkWithIcon } from './logic'; +import { ItemLink } from './types'; + +interface ContactPageItemLinksProps { + links: ItemLink[]; +} + +export const ContactPageItemLinks = ({ links }: ContactPageItemLinksProps) => { + return ( + + {links.map(({ id, titleAboveLink, href, label, linkType }) => ( +
+ {titleAboveLink && ( + + {titleAboveLink} + + )} + + {renderLinkWithIcon(href, label, linkType)} +
+ ))} +
+ ); +}; + +const LinkListItem = styled.div` + border-radius: ${radii[1]}px; + border: 1px solid ${colors.gray3}; + display: inline-block; + padding: ${space[2]} ${space[3]}; + transition: all 0.2s; + + &:hover { + background-color: ${colors.blue8}; + + a { + color: ${colors.white}; + } + } +`; diff --git a/packages/app/src/components/contact/types.ts b/packages/app/src/components/contact/types.ts new file mode 100644 index 0000000000..93f858e8a0 --- /dev/null +++ b/packages/app/src/components/contact/types.ts @@ -0,0 +1,32 @@ +import { RichContentBlock } from '~/types/cms'; + +export type LinkType = 'regular' | 'email' | 'phone'; + +interface Base { + title: string; + id: string; +} + +export interface ItemLink { + id: string; + href: string; + label: string; + linkType: LinkType; + titleAboveLink?: string; +} + +export interface GroupItem extends Base { + description: RichContentBlock[]; + links?: ItemLink[]; + titleUrl?: string; + linkType?: LinkType; +} + +interface PageGroups extends Base { + items: GroupItem[]; +} + +export interface ContactPage { + groups: PageGroups[]; + pageTitle?: string | null; +} diff --git a/packages/app/src/pages/contact.tsx b/packages/app/src/pages/contact.tsx index c5ca36649f..f3b4ed53a5 100644 --- a/packages/app/src/pages/contact.tsx +++ b/packages/app/src/pages/contact.tsx @@ -1,70 +1,37 @@ -import { colors } from '@corona-dashboard/common'; -import { ChevronRight, External, Telephone } from '@corona-dashboard/icons'; import Head from 'next/head'; -import styled from 'styled-components'; import { Box } from '~/components/base/box'; -import { RichContent } from '~/components/cms/rich-content'; -import { ExternalLink } from '~/components/external-link'; +import { ContactPageGroupItem } from '~/components/contact/item'; +import { ContactPage } from '~/components/contact/types'; import { Heading } from '~/components/typography'; import { Layout } from '~/domain/layout/layout'; import { useIntl } from '~/intl'; import { StaticProps, createGetStaticProps } from '~/static-props/create-get-static-props'; import { createGetContent, getLastGeneratedDate } from '~/static-props/get-data'; -import { radii, sizes, space } from '~/style/theme'; -import { RichContentBlock } from '~/types/cms'; -import { isInternalUrl } from '~/utils/is-internal-url'; -import { Link } from '~/utils/link'; - -type LinkType = 'regular' | 'email' | 'phone'; - -interface ItemLink { - id: string; - linkHref: string; - linkLabel: string; - linkType: LinkType; - titleAboveLink?: string; -} -interface GroupItem { - description: RichContentBlock[]; - id: string; - itemTitle: string; - itemLinks?: ItemLink[]; - itemTitleUrl?: string; - linkType?: LinkType; -} - -interface PageGroups { - id: string; - groupTitle: string; - groupItems: GroupItem[]; -} -interface ContactPage { - pageGroups: PageGroups[]; - pageTitle?: string | null; -} +import { sizes, space } from '~/style/theme'; export const getStaticProps = createGetStaticProps( getLastGeneratedDate, createGetContent((context) => { const { locale } = context; - return `*[_type == 'contact'] { - 'pageTitle': title.${locale}, - 'pageGroups': contactPageGroups[]->{ + return `// groq + *[_type == 'contact'] { + 'title': title.${locale}, + 'groups': contactPageGroups[]->{ 'id': _id, - 'groupTitle': title.${locale}, - 'groupItems': contactPageGroupItems[]->{ + 'title': title.${locale}, + 'items': contactPageGroupItems[]->{ 'id': _id, - 'itemTitle': title.${locale}, - 'itemTitleUrl': itemTitleUrl, + 'title': title.${locale}, + 'titleUrl': itemTitleUrl, 'linkType': linkType.linkType, 'description': description.${locale}, - 'itemLinks': contactPageItemLinks[]{ + 'links': contactPageItemLinks[] { 'id': _id, 'titleAboveLink': title.${locale}, 'linkType': linkType.linkType, - 'linkLabel': link.title.${locale}, - 'linkHref': link.href + 'label': link.title.${locale}, + 'href': link.href } } } @@ -72,46 +39,10 @@ export const getStaticProps = createGetStaticProps( }) ); -const formatLinkAccordingToType = (href: string, linkType: LinkType | undefined) => { - switch (linkType) { - case 'email': - return `mailto:${href}`; - case 'phone': - return `tel:${href.replace(/\s/g, '').replace('-', '')}`; - default: - return href; - } -}; - -const renderLinkWithIcon = (href: string, linkText: string, linkType: LinkType | undefined) => { - if (isInternalUrl(href)) { - return ( - - - - {linkText} - - - - - ); - } - - return ( - - - {linkType === 'phone' && } - {linkText} - {linkType !== 'phone' && } - - - ); -}; - const Contact = (props: StaticProps) => { const { commonTexts } = useIntl(); const { - content: { pageTitle, pageGroups }, + content: { pageTitle, groups }, lastGenerated, } = props; @@ -125,108 +56,25 @@ const Contact = (props: StaticProps) => { {/* The dimensions of this box are duplicated on the FAQ and about page, abstract if possible */} {pageTitle && ( - - {pageTitle} - + + {pageTitle} + )} - { - // Consider using some unique ID instead of index - pageGroups.map((group) => { - const { id, groupTitle, groupItems } = group; - return ( - - - {groupTitle} - - - {groupItems.map((item, index) => { - const { id, itemTitle, itemTitleUrl, linkType, description, itemLinks } = item; - - return ( - - - {itemTitleUrl ? {renderLinkWithIcon(itemTitleUrl, itemTitle, linkType)} : {itemTitle}} - - - - - {itemLinks && } - - ); - })} - - ); - }) - } + {groups.map(({ id, title, items }) => ( +
+ + {title} + + + {items.map((item, index) => ( + + ))} +
+ ))}
); }; -interface LinkWrapperProps { - iconMargin: string; -} - -const LinkWrapper = styled.div` - a { - align-items: center; - display: flex; - } - - svg { - height: 16px; - margin: ${({ iconMargin }) => iconMargin}; - width: 16px; - } -`; - -const LinkListItem = styled.div` - border-radius: ${radii[1]}px; - border: 1px solid ${colors.gray3}; - display: inline-block; - padding: ${space[2]} ${space[3]}; - transition: all 0.2s; - - &:hover { - background-color: ${colors.blue8}; - - a { - color: ${colors.white}; - } - } -`; - -const RichContentWrapper = styled.div` - width: 100%; -`; - -interface ContactPageItemLinksProps { - links: ItemLink[]; -} - -const ContactPageItemLinks = ({ links }: ContactPageItemLinksProps) => { - return ( - - {links.map(({ id, titleAboveLink, linkHref, linkLabel, linkType }) => ( - - {titleAboveLink && ( - - {titleAboveLink} - - )} - - {renderLinkWithIcon(linkHref, linkLabel, linkType)} - - ))} - - ); -}; - export default Contact; From ad96e9f81406a369d3c5574472180c294aba39ea Mon Sep 17 00:00:00 2001 From: VWSCoronaDashboard28 Date: Mon, 18 Sep 2023 14:38:58 +0200 Subject: [PATCH 08/12] feat(contact-page-redesign): Remove page title from schema. --- .../cms/src/schemas/documents/pages/contact/index.ts | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/packages/cms/src/schemas/documents/pages/contact/index.ts b/packages/cms/src/schemas/documents/pages/contact/index.ts index 5525370bb9..efb43e11c0 100644 --- a/packages/cms/src/schemas/documents/pages/contact/index.ts +++ b/packages/cms/src/schemas/documents/pages/contact/index.ts @@ -3,16 +3,9 @@ import { defineArrayMember, defineField, defineType } from 'sanity'; export const contact = defineType({ name: 'contact', title: 'Contact Page', - description: - 'Dit is het startpunt voor het configureren van de contactpagina. Stel een optionele titel voor de pagina in en voeg er secties aan toe met behulp van de onderstaande lijst.', + description: 'Dit is het startpunt voor het configureren van de contactpagina. Voeg er secties aan toe met behulp van de onderstaande lijst.', type: 'document', fields: [ - defineField({ - name: 'title', - title: 'Pagina Titel', - description: 'Configureer de titel voor de contactpagina. Het is niet verplicht dit veld in te vullen.', - type: 'localeString', - }), defineField({ name: 'contactPageGroups', title: 'Pagina Groepen', From 6c8a73fe5f94954b7cb6430f1e8a3a635881caf6 Mon Sep 17 00:00:00 2001 From: VWSCoronaDashboard28 Date: Mon, 18 Sep 2023 14:50:03 +0200 Subject: [PATCH 09/12] feat(contact-page-redesign): Refactoring. --- .../components/contact/contact-page-group.tsx | 27 ++++++++ ...{links.tsx => contact-page-item-links.tsx} | 24 +++---- .../{item.tsx => contact-page-item.tsx} | 10 +-- .../components/contact/contact-page-link.tsx | 66 +++++++++++++++++++ packages/app/src/components/contact/types.ts | 5 +- packages/app/src/pages/contact.tsx | 50 +++++++------- 6 files changed, 139 insertions(+), 43 deletions(-) create mode 100644 packages/app/src/components/contact/contact-page-group.tsx rename packages/app/src/components/contact/{links.tsx => contact-page-item-links.tsx} (60%) rename packages/app/src/components/contact/{item.tsx => contact-page-item.tsx} (77%) create mode 100644 packages/app/src/components/contact/contact-page-link.tsx diff --git a/packages/app/src/components/contact/contact-page-group.tsx b/packages/app/src/components/contact/contact-page-group.tsx new file mode 100644 index 0000000000..c27046886e --- /dev/null +++ b/packages/app/src/components/contact/contact-page-group.tsx @@ -0,0 +1,27 @@ +import { space } from '~/style/theme'; +import { Box } from '../base/box'; +import { Heading } from '../typography'; +import { ContactPageGroupItem } from './contact-page-item'; +import { PageGroup } from './types'; + +interface ContactPageGroupProps { + groups: PageGroup[]; +} + +export const ContactPageGroup = ({ groups }: ContactPageGroupProps) => { + return ( + + {groups.map(({ id, title, items }) => ( +
+ + {title} + + + {items.map((item, index) => ( + + ))} +
+ ))} +
+ ); +}; diff --git a/packages/app/src/components/contact/links.tsx b/packages/app/src/components/contact/contact-page-item-links.tsx similarity index 60% rename from packages/app/src/components/contact/links.tsx rename to packages/app/src/components/contact/contact-page-item-links.tsx index a82ee5a213..b86c87e1ab 100644 --- a/packages/app/src/components/contact/links.tsx +++ b/packages/app/src/components/contact/contact-page-item-links.tsx @@ -1,9 +1,9 @@ import { colors } from '@corona-dashboard/common'; import styled from 'styled-components'; -import { radii, space } from '~/style/theme'; +import { mediaQueries, radii, space } from '~/style/theme'; import { Box } from '../base/box'; -import { Heading } from '../typography'; -import { renderLinkWithIcon } from './logic'; +import { BoldText } from '../typography'; +import { ContactPageLink } from './contact-page-link'; import { ItemLink } from './types'; interface ContactPageItemLinksProps { @@ -12,16 +12,14 @@ interface ContactPageItemLinksProps { export const ContactPageItemLinks = ({ links }: ContactPageItemLinksProps) => { return ( - + {links.map(({ id, titleAboveLink, href, label, linkType }) => (
- {titleAboveLink && ( - - {titleAboveLink} - - )} + {titleAboveLink && {titleAboveLink}} - {renderLinkWithIcon(href, label, linkType)} + + +
))}
@@ -31,7 +29,7 @@ export const ContactPageItemLinks = ({ links }: ContactPageItemLinksProps) => { const LinkListItem = styled.div` border-radius: ${radii[1]}px; border: 1px solid ${colors.gray3}; - display: inline-block; + display: block; padding: ${space[2]} ${space[3]}; transition: all 0.2s; @@ -42,4 +40,8 @@ const LinkListItem = styled.div` color: ${colors.white}; } } + + @media ${mediaQueries.sm} { + display: inline-block; + } `; diff --git a/packages/app/src/components/contact/item.tsx b/packages/app/src/components/contact/contact-page-item.tsx similarity index 77% rename from packages/app/src/components/contact/item.tsx rename to packages/app/src/components/contact/contact-page-item.tsx index 73eb621a4a..733f97e9f5 100644 --- a/packages/app/src/components/contact/item.tsx +++ b/packages/app/src/components/contact/contact-page-item.tsx @@ -1,12 +1,12 @@ import { colors } from '@corona-dashboard/common'; +import styled from 'styled-components'; import { radii, space } from '~/style/theme'; import { Box } from '../base/box'; import { RichContent } from '../cms/rich-content'; import { Heading } from '../typography'; -import styled from 'styled-components'; +import { ContactPageLink } from './contact-page-link'; +import { ContactPageItemLinks } from './contact-page-item-links'; import { GroupItem } from './types'; -import { renderLinkWithIcon } from './logic'; -import { ContactPageItemLinks } from './links'; interface ContactPageGroupItemProps { groupItemsLength: number; @@ -19,8 +19,8 @@ export const ContactPageGroupItem = ({ item, index, groupItemsLength }: ContactP return ( - - {titleUrl ? renderLinkWithIcon(titleUrl, title, linkType) : title} + + {titleUrl ? : title} diff --git a/packages/app/src/components/contact/contact-page-link.tsx b/packages/app/src/components/contact/contact-page-link.tsx new file mode 100644 index 0000000000..0794d8acd1 --- /dev/null +++ b/packages/app/src/components/contact/contact-page-link.tsx @@ -0,0 +1,66 @@ +import { ChevronRight, External, Telephone } from '@corona-dashboard/icons'; +import styled from 'styled-components'; +import { ExternalLink } from '~/components/external-link'; +import { space } from '~/style/theme'; +import { isInternalUrl } from '~/utils/is-internal-url'; +import { Link } from '~/utils/link'; +import { LinkType } from './types'; + +interface ContactPageLinkProps { + href: string; + label: string; + linkType: LinkType | undefined; +} + +export const ContactPageLink = ({ href, label, linkType }: ContactPageLinkProps) => { + const formatLinkAccordingToType = (href: string, linkType: LinkType | undefined) => { + switch (linkType) { + case 'email': + return `mailto:${href}`; + case 'phone': + return `tel:${href.replace(/\s/g, '').replace('-', '')}`; + default: + return href; + } + }; + + if (isInternalUrl(href)) { + return ( + + + + {label} + + + + + ); + } + + return ( + + + {linkType === 'phone' && } + {label} + {linkType !== 'phone' && } + + + ); +}; + +interface LinkWrapperProps { + iconMargin: string; +} + +const LinkWrapper = styled.div` + a { + align-items: center; + display: flex; + } + + svg { + height: 16px; + margin: ${({ iconMargin }) => iconMargin}; + width: 16px; + } +`; diff --git a/packages/app/src/components/contact/types.ts b/packages/app/src/components/contact/types.ts index 93f858e8a0..d01f33a080 100644 --- a/packages/app/src/components/contact/types.ts +++ b/packages/app/src/components/contact/types.ts @@ -22,11 +22,10 @@ export interface GroupItem extends Base { linkType?: LinkType; } -interface PageGroups extends Base { +export interface PageGroup extends Base { items: GroupItem[]; } export interface ContactPage { - groups: PageGroups[]; - pageTitle?: string | null; + groups: PageGroup[]; } diff --git a/packages/app/src/pages/contact.tsx b/packages/app/src/pages/contact.tsx index f3b4ed53a5..30cde7ba17 100644 --- a/packages/app/src/pages/contact.tsx +++ b/packages/app/src/pages/contact.tsx @@ -1,13 +1,15 @@ import Head from 'next/head'; -import { Box } from '~/components/base/box'; -import { ContactPageGroupItem } from '~/components/contact/item'; +import styled from 'styled-components'; +import { VisuallyHidden } from '~/components'; +import { ContactPageGroup } from '~/components/contact/contact-page-group'; import { ContactPage } from '~/components/contact/types'; import { Heading } from '~/components/typography'; +import { ContentLayout } from '~/domain/layout/content-layout'; import { Layout } from '~/domain/layout/layout'; import { useIntl } from '~/intl'; import { StaticProps, createGetStaticProps } from '~/static-props/create-get-static-props'; import { createGetContent, getLastGeneratedDate } from '~/static-props/get-data'; -import { sizes, space } from '~/style/theme'; +import { mediaQueries, space } from '~/style/theme'; export const getStaticProps = createGetStaticProps( getLastGeneratedDate, @@ -16,7 +18,6 @@ export const getStaticProps = createGetStaticProps( return `// groq *[_type == 'contact'] { - 'title': title.${locale}, 'groups': contactPageGroups[]->{ 'id': _id, 'title': title.${locale}, @@ -42,10 +43,14 @@ export const getStaticProps = createGetStaticProps( const Contact = (props: StaticProps) => { const { commonTexts } = useIntl(); const { - content: { pageTitle, groups }, + content: { groups }, lastGenerated, } = props; + const middleIndexOfGroups = Math.ceil(groups.length / 2); + const firstHalf = groups.slice(0, middleIndexOfGroups); + const secondHalf = groups.slice(middleIndexOfGroups); + return ( @@ -53,28 +58,25 @@ const Contact = (props: StaticProps) => { - {/* The dimensions of this box are duplicated on the FAQ and about page, abstract if possible */} - - {pageTitle && ( - - {pageTitle} - - )} - - {groups.map(({ id, title, items }) => ( -
- - {title} - + + Contact + - {items.map((item, index) => ( - - ))} -
- ))} -
+ + + + + +
); }; +const ContactLayout = styled.div` + @media ${mediaQueries.sm} { + display: flex; + gap: ${space[4]} ${space[5]}; + } +`; + export default Contact; From d36598e0b5b2e4e6f63ad0b0e08e156182b4194c Mon Sep 17 00:00:00 2001 From: VWSCoronaDashboard28 Date: Mon, 18 Sep 2023 14:51:08 +0200 Subject: [PATCH 10/12] feat(contact-page-redesign): Create content layout and reuse on content pages. --- packages/app/src/domain/layout/content-layout.tsx | 14 ++++++++++++++ packages/app/src/pages/over.tsx | 5 +++-- packages/app/src/pages/veelgestelde-vragen.tsx | 5 +++-- 3 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 packages/app/src/domain/layout/content-layout.tsx diff --git a/packages/app/src/domain/layout/content-layout.tsx b/packages/app/src/domain/layout/content-layout.tsx new file mode 100644 index 0000000000..b0fb00ea77 --- /dev/null +++ b/packages/app/src/domain/layout/content-layout.tsx @@ -0,0 +1,14 @@ +import { Box } from '~/components/base/box'; +import { sizes, space } from '~/style/theme'; + +interface ContentLayoutProps { + children?: React.ReactNode; +} + +export const ContentLayout = ({ children }: ContentLayoutProps) => { + return ( + + {children} + + ); +}; diff --git a/packages/app/src/pages/over.tsx b/packages/app/src/pages/over.tsx index ed7bd73620..7c48cc01d8 100644 --- a/packages/app/src/pages/over.tsx +++ b/packages/app/src/pages/over.tsx @@ -5,6 +5,7 @@ import { ContentImage } from '~/components/cms/content-image'; import { RichContent } from '~/components/cms/rich-content'; import { FullscreenChartTile } from '~/components/fullscreen-chart-tile'; import { Heading } from '~/components/typography'; +import { ContentLayout } from '~/domain/layout/content-layout'; import { Layout } from '~/domain/layout/layout'; import { useIntl } from '~/intl'; import { createGetStaticProps, StaticProps } from '~/static-props/create-get-static-props'; @@ -60,7 +61,7 @@ const Over = (props: StaticProps) => { return ( - + @@ -85,7 +86,7 @@ const Over = (props: StaticProps) => { -
+ ); }; diff --git a/packages/app/src/pages/veelgestelde-vragen.tsx b/packages/app/src/pages/veelgestelde-vragen.tsx index b09608ebe4..331d3e25b2 100644 --- a/packages/app/src/pages/veelgestelde-vragen.tsx +++ b/packages/app/src/pages/veelgestelde-vragen.tsx @@ -5,6 +5,7 @@ import { Box } from '~/components/base/box'; import { RichContent } from '~/components/cms/rich-content'; import { FaqSection } from '~/components/faq/faq-section'; import { Heading } from '~/components/typography'; +import { ContentLayout } from '~/domain/layout/content-layout'; import { Layout } from '~/domain/layout/layout'; import { useIntl } from '~/intl'; import { createGetStaticProps, StaticProps } from '~/static-props/create-get-static-props'; @@ -68,7 +69,7 @@ const Verantwoording = (props: StaticProps) => { return ( - + @@ -87,7 +88,7 @@ const Verantwoording = (props: StaticProps) => { - + ); }; From b5d2c60d7d3d9d354076f9f47f240156021b074d Mon Sep 17 00:00:00 2001 From: VWSCoronaDashboard28 Date: Mon, 18 Sep 2023 15:13:31 +0200 Subject: [PATCH 11/12] feat(contact-page-redesign): Add utility and unit test. --- .../components/contact/contact-page-link.tsx | 12 +------ .../format-link-according-to-type.spec.ts | 34 +++++++++++++++++++ .../utils/format-link-according-to-type.ts | 13 +++++++ 3 files changed, 48 insertions(+), 11 deletions(-) create mode 100644 packages/app/src/utils/__tests__/format-link-according-to-type.spec.ts create mode 100644 packages/app/src/utils/format-link-according-to-type.ts diff --git a/packages/app/src/components/contact/contact-page-link.tsx b/packages/app/src/components/contact/contact-page-link.tsx index 0794d8acd1..e7896b39f0 100644 --- a/packages/app/src/components/contact/contact-page-link.tsx +++ b/packages/app/src/components/contact/contact-page-link.tsx @@ -2,6 +2,7 @@ import { ChevronRight, External, Telephone } from '@corona-dashboard/icons'; import styled from 'styled-components'; import { ExternalLink } from '~/components/external-link'; import { space } from '~/style/theme'; +import { formatLinkAccordingToType } from '~/utils/format-link-according-to-type'; import { isInternalUrl } from '~/utils/is-internal-url'; import { Link } from '~/utils/link'; import { LinkType } from './types'; @@ -13,17 +14,6 @@ interface ContactPageLinkProps { } export const ContactPageLink = ({ href, label, linkType }: ContactPageLinkProps) => { - const formatLinkAccordingToType = (href: string, linkType: LinkType | undefined) => { - switch (linkType) { - case 'email': - return `mailto:${href}`; - case 'phone': - return `tel:${href.replace(/\s/g, '').replace('-', '')}`; - default: - return href; - } - }; - if (isInternalUrl(href)) { return ( diff --git a/packages/app/src/utils/__tests__/format-link-according-to-type.spec.ts b/packages/app/src/utils/__tests__/format-link-according-to-type.spec.ts new file mode 100644 index 0000000000..4bff96a984 --- /dev/null +++ b/packages/app/src/utils/__tests__/format-link-according-to-type.spec.ts @@ -0,0 +1,34 @@ +import { suite } from 'uvu'; +import * as assert from 'uvu/assert'; +import { formatLinkAccordingToType } from '../format-link-according-to-type'; + +const FormatLinkAccordingToType = suite('formatLinkAccordingToType'); + +FormatLinkAccordingToType('should not do anything to a regular link', () => { + const linkType = 'regular'; + const href = '/'; + + const result = formatLinkAccordingToType(href, linkType); + + assert.is(result, '/'); +}); + +FormatLinkAccordingToType('should format as a telephone link', () => { + const linkType = 'phone'; + const href = '123-456-789'; + + const result = formatLinkAccordingToType(href, linkType); + + assert.is(result, 'tel:123456789'); +}); + +FormatLinkAccordingToType('should format as a email link', () => { + const linkType = 'email'; + const href = 'test@test.com'; + + const result = formatLinkAccordingToType(href, linkType); + + assert.is(result, 'mailto:test@test.com'); +}); + +FormatLinkAccordingToType.run(); diff --git a/packages/app/src/utils/format-link-according-to-type.ts b/packages/app/src/utils/format-link-according-to-type.ts new file mode 100644 index 0000000000..5223ef69f1 --- /dev/null +++ b/packages/app/src/utils/format-link-according-to-type.ts @@ -0,0 +1,13 @@ +/** + * Returns a formatted link based on the link type of email, phone, regular + */ +export const formatLinkAccordingToType = (href: string, linkType: string | undefined) => { + switch (linkType) { + case 'email': + return `mailto:${href}`; + case 'phone': + return `tel:${href.replace(/\s/g, '').replaceAll('-', '')}`; + default: + return href; + } +}; From 4708a1e13c8d87572aa0be046804257827cdb408 Mon Sep 17 00:00:00 2001 From: VWSCoronaDashboard28 Date: Mon, 18 Sep 2023 15:36:29 +0200 Subject: [PATCH 12/12] feat(contact-page-redesign): Spacing fix. --- .../src/components/contact/contact-page-item-links.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/app/src/components/contact/contact-page-item-links.tsx b/packages/app/src/components/contact/contact-page-item-links.tsx index b86c87e1ab..6f24a26640 100644 --- a/packages/app/src/components/contact/contact-page-item-links.tsx +++ b/packages/app/src/components/contact/contact-page-item-links.tsx @@ -2,7 +2,7 @@ import { colors } from '@corona-dashboard/common'; import styled from 'styled-components'; import { mediaQueries, radii, space } from '~/style/theme'; import { Box } from '../base/box'; -import { BoldText } from '../typography'; +import { Text } from '../typography'; import { ContactPageLink } from './contact-page-link'; import { ItemLink } from './types'; @@ -15,7 +15,11 @@ export const ContactPageItemLinks = ({ links }: ContactPageItemLinksProps) => { {links.map(({ id, titleAboveLink, href, label, linkType }) => (
- {titleAboveLink && {titleAboveLink}} + {titleAboveLink && ( + + {titleAboveLink} + + )}