From db09879f63c983d2f1b87b802137d13182dbac3d Mon Sep 17 00:00:00 2001 From: Guilherme Popolin Date: Fri, 7 Jul 2023 10:54:09 +0200 Subject: [PATCH] feat: added TrustpilotBlock --- apps/store/public/locales/en/common.json | 2 + apps/store/public/locales/sv-se/common.json | 2 + apps/store/src/blocks/TrustpilotBlock.tsx | 71 +++++++++++++++++++ .../TrustpilotLogo/TrustpilotLogo.tsx | 27 +++++++ .../store/src/services/storyblok/storyblok.ts | 2 + apps/store/src/utils/formatter.ts | 4 ++ 6 files changed, 108 insertions(+) create mode 100644 apps/store/src/blocks/TrustpilotBlock.tsx create mode 100644 apps/store/src/components/TrustpilotLogo/TrustpilotLogo.tsx diff --git a/apps/store/public/locales/en/common.json b/apps/store/public/locales/en/common.json index 745c806071..b5ed1550a2 100644 --- a/apps/store/public/locales/en/common.json +++ b/apps/store/public/locales/en/common.json @@ -41,5 +41,7 @@ "PAYMENT_CONNECT_TITLE": "Connect direct debit", "READ_MORE": "Read more", "SELECT_INSURANCE": "Select insurance", + "TRUSTPILOT_REVIEWS_COUNT": "Based on {{numberOfReviews}} reviews on", + "TRUSTPILOT_SCORE": "{{score}} of 5", "UNKNOWN_ERROR_MESSAGE": "Something went wrong, please try again." } \ No newline at end of file diff --git a/apps/store/public/locales/sv-se/common.json b/apps/store/public/locales/sv-se/common.json index 7400666aac..4a71ede6f3 100644 --- a/apps/store/public/locales/sv-se/common.json +++ b/apps/store/public/locales/sv-se/common.json @@ -38,5 +38,7 @@ "PAYMENT_CONNECT_TITLE": "Koppla autogiro", "READ_MORE": "Läs mer", "SELECT_INSURANCE": "Välj försäkring", + "TRUSTPILOT_REVIEWS_COUNT": "Baserat på {{numberOfReviews}} recensioner på", + "TRUSTPILOT_SCORE": "{{score}} av 5", "UNKNOWN_ERROR_MESSAGE": "Något gick fel, försök igen." } \ No newline at end of file diff --git a/apps/store/src/blocks/TrustpilotBlock.tsx b/apps/store/src/blocks/TrustpilotBlock.tsx new file mode 100644 index 0000000000..d00c2d5f2f --- /dev/null +++ b/apps/store/src/blocks/TrustpilotBlock.tsx @@ -0,0 +1,71 @@ +import styled from '@emotion/styled' +import { storyblokEditable } from '@storyblok/react' +import { useTranslation } from 'react-i18next' +import { Text, theme, mq } from 'ui' +import { TrustpilotLogo } from '@/components/TrustpilotLogo/TrustpilotLogo' +import { SbBaseBlockProps } from '@/services/storyblok/storyblok' +import { useTrustpilotData } from '@/services/trustpilot/trustpilot' +import { useFormatter } from '@/utils/useFormatter' + +export const TrustpilotBlock = ({ blok }: SbBaseBlockProps) => { + const { t } = useTranslation('common') + const { numberGrouping } = useFormatter() + const data = useTrustpilotData() + + if (!data) { + console.warn('[TrustpilotBlock]: No Trustpilot data found. Skip rendering.') + return null + } + + return ( + + + + {t('TRUSTPILOT_SCORE', { score: data.score })} + + + {t('TRUSTPILOT_REVIEWS_COUNT', { + numberOfReviews: numberGrouping(data.totalReviews), + })} + + + + + ) +} + +const Wrapper = styled.div({ + display: 'grid', + placeItems: 'center', + backgroundColor: theme.colors.signalGreenFill, + paddingBlock: '10rem', + paddingInline: '1rem', +}) + +const Link = styled.a({ + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + justifyContent: 'center', + gap: theme.space.md, +}) + +const ScoreText = styled(Text)({ + lineHeight: '132%', + // Font size tihs high is an edge case. That's why I'm not using Text's 'size' prop + [mq.lg]: { + fontSize: '12.5rem', + }, +}) + +const ReviewText = styled(Text)({ + display: 'inline-flex', + alignItems: 'center', + gap: theme.space.xxs, + + [mq.lg]: { + gap: theme.space.xs, + }, +}) + +TrustpilotBlock.blockName = 'trustpilot' diff --git a/apps/store/src/components/TrustpilotLogo/TrustpilotLogo.tsx b/apps/store/src/components/TrustpilotLogo/TrustpilotLogo.tsx new file mode 100644 index 0000000000..9b81b51092 --- /dev/null +++ b/apps/store/src/components/TrustpilotLogo/TrustpilotLogo.tsx @@ -0,0 +1,27 @@ +export type Props = { + width?: number | string + height?: number | string +} + +export const TrustpilotLogo = (props: Props) => { + return ( + + + + + + + + + + + + + ) +} diff --git a/apps/store/src/services/storyblok/storyblok.ts b/apps/store/src/services/storyblok/storyblok.ts index fc1277e3f6..c203b42c3c 100644 --- a/apps/store/src/services/storyblok/storyblok.ts +++ b/apps/store/src/services/storyblok/storyblok.ts @@ -63,6 +63,7 @@ import { TextContentBlock } from '@/blocks/TextContentBlock' import { TimelineBlock } from '@/blocks/TimelineBlock' import { TimelineItemBlock } from '@/blocks/TimelineItemBlock' import { TopPickCardBlock } from '@/blocks/TopPickCardBlock' +import { TrustpilotBlock } from '@/blocks/TrustpilotBlock' import { USPBlock, USPBlockItem } from '@/blocks/USPBlock' import { VideoBlock } from '@/blocks/VideoBlock' import { VideoListBlock } from '@/blocks/VideoListBlock' @@ -278,6 +279,7 @@ export const initStoryblok = () => { TextBlock, TextContentBlock, TopPickCardBlock, + TrustpilotBlock, VideoBlock, VideoListBlock, ProductNavContainerBlock, diff --git a/apps/store/src/utils/formatter.ts b/apps/store/src/utils/formatter.ts index b5d0a7d88c..a5c3a8dd77 100644 --- a/apps/store/src/utils/formatter.ts +++ b/apps/store/src/utils/formatter.ts @@ -79,6 +79,9 @@ const formatZipCode = (value: string): string => { return value.replace(/(\d{3})(\d{2})/, '$1 $2') } +const formatNumberGrouping = (value: number, locale: string) => + new Intl.NumberFormat(locale, { useGrouping: true }).format(value) + type FormatterOptions = MoneyFormatOptions & { t: TFunction } export class Formatter { @@ -100,4 +103,5 @@ export class Formatter { public ssn = formatSsn public carRegistrationNumber = formatCarRegistrationNumber public zipCode = formatZipCode + public numberGrouping = (value: number) => formatNumberGrouping(value, this.options.locale) }