-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f411945
commit 6672bce
Showing
14 changed files
with
253 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<unknown>) => { | ||
const { t } = useTranslation('common') | ||
const { numberGrouping } = useFormatter() | ||
const data = useTrustpilotData() | ||
|
||
if (!data) { | ||
console.warn('[TrustpilotBlock]: No Trustpilot data found. Skip rendering.') | ||
return null | ||
} | ||
|
||
return ( | ||
<Wrapper {...storyblokEditable(blok)}> | ||
<Link href="https://www.trustpilot.com/review/www.hedvig.com" target="_blank" rel="noopener"> | ||
<ScoreText as="span" size={11}> | ||
{t('TRUSTPILOT_SCORE', { score: data.score })} | ||
</ScoreText> | ||
<ReviewText as="span" color="textGreen" size={{ _: 'xs', lg: 'xl' }}> | ||
{t('TRUSTPILOT_REVIEWS_COUNT', { | ||
numberOfReviews: numberGrouping(data.totalReviews), | ||
})} | ||
<TrustpilotLogo width="5.5em" /> | ||
</ReviewText> | ||
</Link> | ||
</Wrapper> | ||
) | ||
} | ||
|
||
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' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 27 additions & 0 deletions
27
apps/store/src/components/TrustpilotLogo/TrustpilotLogo.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
export type Props = { | ||
width?: number | string | ||
height?: number | string | ||
} | ||
|
||
export const TrustpilotLogo = (props: Props) => { | ||
return ( | ||
<svg viewBox="0 0 136 33" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}> | ||
<g clip-path="url(#clip0_1665_6714)"> | ||
<path | ||
d="M36.133 11.6961H49.7388V14.2346H44.389V28.5045H41.4472V14.2346H36.1211V11.6961H36.133ZM49.1576 16.3341H51.6723V18.6828H51.7198C51.8028 18.3507 51.957 18.0304 52.1824 17.722C52.4078 17.4136 52.6806 17.117 53.0009 16.8679C53.3212 16.607 53.677 16.4053 54.0685 16.2392C54.4599 16.085 54.8632 16.002 55.2665 16.002C55.575 16.002 55.8003 16.0139 55.919 16.0257C56.0376 16.0376 56.1562 16.0613 56.2867 16.0732V18.6591C56.0969 18.6235 55.9071 18.5998 55.7054 18.576C55.5038 18.5523 55.314 18.5405 55.1242 18.5405C54.6734 18.5405 54.2464 18.6354 53.8431 18.8133C53.4398 18.9912 53.0958 19.264 52.7992 19.608C52.5027 19.9639 52.2654 20.3909 52.0875 20.9129C51.9096 21.4348 51.8265 22.0279 51.8265 22.704V28.4927H49.1457V16.3341H49.1576ZM68.6114 28.5045H65.978V26.8083H65.9306C65.5984 27.4251 65.1121 27.9114 64.4597 28.2791C63.8073 28.6469 63.143 28.8367 62.4668 28.8367C60.8655 28.8367 59.703 28.4452 58.9912 27.6505C58.2795 26.8557 57.9237 25.6576 57.9237 24.0563V16.3341H60.6045V23.7953C60.6045 24.8629 60.8062 25.6221 61.2213 26.061C61.6246 26.4998 62.2059 26.7252 62.9413 26.7252C63.5107 26.7252 63.9733 26.6422 64.3529 26.4643C64.7325 26.2863 65.0409 26.061 65.2663 25.7644C65.5035 25.4797 65.6696 25.1239 65.7764 24.7205C65.8831 24.3172 65.9306 23.8783 65.9306 23.4039V16.346H68.6114V28.5045ZM73.1783 24.6019C73.2614 25.3848 73.5579 25.9305 74.068 26.2507C74.5899 26.5592 75.2068 26.7252 75.9303 26.7252C76.1795 26.7252 76.4641 26.7015 76.7844 26.6659C77.1047 26.6303 77.4131 26.5473 77.6859 26.4405C77.9706 26.3338 78.196 26.1677 78.3858 25.9542C78.5637 25.7407 78.6468 25.4679 78.6349 25.1239C78.623 24.7799 78.4926 24.4952 78.2553 24.2817C78.0181 24.0563 77.7215 23.8902 77.3538 23.7479C76.9861 23.6174 76.5709 23.4988 76.0964 23.4039C75.6219 23.309 75.1474 23.2022 74.6611 23.0955C74.1629 22.9887 73.6765 22.8464 73.2139 22.6922C72.7513 22.5379 72.3361 22.3244 71.9684 22.0516C71.6007 21.7906 71.3041 21.4466 71.0906 21.0315C70.8652 20.6163 70.7585 20.1062 70.7585 19.4894C70.7585 18.8252 70.9245 18.2795 71.2448 17.8287C71.5651 17.378 71.9803 17.0221 72.4666 16.7493C72.9648 16.4765 73.5105 16.2867 74.1154 16.1681C74.7204 16.0613 75.3017 16.002 75.8473 16.002C76.476 16.002 77.081 16.0732 77.6504 16.2037C78.2197 16.3341 78.7417 16.5477 79.2043 16.8561C79.6669 17.1526 80.0465 17.5441 80.3549 18.0185C80.6633 18.493 80.8531 19.0743 80.9362 19.7504H78.1367C78.0062 19.1098 77.7215 18.6709 77.2589 18.4574C76.7963 18.2321 76.2625 18.1253 75.6694 18.1253C75.4796 18.1253 75.2542 18.1372 74.9932 18.1727C74.7323 18.2083 74.495 18.2676 74.2578 18.3507C74.0324 18.4337 73.8426 18.5642 73.6765 18.7303C73.5223 18.8963 73.4393 19.1098 73.4393 19.3827C73.4393 19.7148 73.5579 19.9758 73.7833 20.1774C74.0087 20.3791 74.3052 20.5451 74.673 20.6875C75.0407 20.818 75.4559 20.9366 75.9303 21.0315C76.4048 21.1264 76.8912 21.2331 77.3894 21.3399C77.8757 21.4466 78.3502 21.589 78.8247 21.7432C79.2992 21.8974 79.7144 22.1109 80.0821 22.3837C80.4498 22.6566 80.7464 22.9887 80.9717 23.392C81.1971 23.7953 81.3157 24.3054 81.3157 24.8985C81.3157 25.6221 81.1497 26.227 80.8175 26.7371C80.4854 27.2353 80.0584 27.6505 79.5364 27.9589C79.0145 28.2673 78.4214 28.5045 77.7808 28.6469C77.1403 28.7892 76.4997 28.8604 75.871 28.8604C75.1 28.8604 74.3883 28.7773 73.7359 28.5994C73.0834 28.4215 72.5141 28.1605 72.0396 27.8165C71.5651 27.4607 71.1855 27.0218 70.9127 26.4998C70.6398 25.9779 70.4975 25.3492 70.4738 24.6257H73.1783V24.6019ZM82.0275 16.3341H84.0559V12.6806H86.7367V16.3341H89.1566V18.3388H86.7367V24.8392C86.7367 25.1239 86.7486 25.3611 86.7723 25.5746C86.796 25.7763 86.8554 25.9542 86.9384 26.0965C87.0214 26.2389 87.1519 26.3456 87.3298 26.4168C87.5078 26.488 87.7331 26.5236 88.0416 26.5236C88.2314 26.5236 88.4211 26.5236 88.6109 26.5117C88.8007 26.4998 88.9905 26.4761 89.1803 26.4287V28.5045C88.8838 28.5401 88.5872 28.5638 88.3144 28.5994C88.0297 28.635 87.745 28.6469 87.4485 28.6469C86.7367 28.6469 86.1674 28.5757 85.7403 28.4452C85.3133 28.3147 84.9693 28.1131 84.732 27.8521C84.4829 27.5911 84.3287 27.2709 84.2338 26.8794C84.1508 26.488 84.0915 26.0372 84.0796 25.539V18.3625H82.0512V16.3341H82.0275ZM91.0545 16.3341H93.593V17.983H93.6405C94.0201 17.2712 94.542 16.773 95.2181 16.4646C95.8943 16.1562 96.6179 16.002 97.4126 16.002C98.3735 16.002 99.2038 16.1681 99.9155 16.5121C100.627 16.8442 101.22 17.3068 101.695 17.8999C102.169 18.493 102.513 19.181 102.751 19.9639C102.988 20.7468 103.106 21.589 103.106 22.4786C103.106 23.2971 103 24.0919 102.786 24.851C102.573 25.6221 102.252 26.2982 101.825 26.8913C101.398 27.4844 100.853 27.947 100.188 28.3029C99.5241 28.6587 98.7531 28.8367 97.8515 28.8367C97.4601 28.8367 97.0686 28.8011 96.6772 28.7299C96.2857 28.6587 95.9061 28.5401 95.5503 28.3859C95.1944 28.2317 94.8504 28.03 94.5539 27.7809C94.2454 27.5318 93.9963 27.2471 93.7828 26.9269H93.7354V33.0002H91.0545V16.3341ZM100.426 22.4312C100.426 21.8855 100.354 21.3518 100.212 20.8298C100.07 20.3079 99.8562 19.8571 99.5715 19.4538C99.2869 19.0505 98.931 18.7303 98.5158 18.493C98.0888 18.2558 97.6024 18.1253 97.0568 18.1253C95.9299 18.1253 95.0758 18.5167 94.5064 19.2996C93.937 20.0825 93.6523 21.1264 93.6523 22.4312C93.6523 23.048 93.7235 23.6174 93.8777 24.1393C94.0319 24.6612 94.2454 25.112 94.5539 25.4916C94.8504 25.8712 95.2063 26.1677 95.6215 26.3812C96.0366 26.6066 96.523 26.7134 97.0686 26.7134C97.6855 26.7134 98.1955 26.5829 98.6226 26.3338C99.0496 26.0847 99.3936 25.7525 99.6664 25.3611C99.9393 24.9578 100.141 24.507 100.26 23.997C100.366 23.4869 100.426 22.965 100.426 22.4312ZM105.159 11.6961H107.839V14.2346H105.159V11.6961ZM105.159 16.3341H107.839V28.5045H105.159V16.3341ZM110.236 11.6961H112.916V28.5045H110.236V11.6961ZM121.137 28.8367C120.164 28.8367 119.298 28.6706 118.539 28.3503C117.78 28.03 117.139 27.5793 116.606 27.0218C116.084 26.4524 115.68 25.7763 115.407 24.9934C115.135 24.2105 114.992 23.3446 114.992 22.4075C114.992 21.4822 115.135 20.6282 115.407 19.8453C115.68 19.0624 116.084 18.3863 116.606 17.8169C117.127 17.2475 117.78 16.8086 118.539 16.4883C119.298 16.1681 120.164 16.002 121.137 16.002C122.11 16.002 122.975 16.1681 123.735 16.4883C124.494 16.8086 125.134 17.2594 125.668 17.8169C126.19 18.3863 126.593 19.0624 126.866 19.8453C127.139 20.6282 127.281 21.4822 127.281 22.4075C127.281 23.3446 127.139 24.2105 126.866 24.9934C126.593 25.7763 126.19 26.4524 125.668 27.0218C125.146 27.5911 124.494 28.03 123.735 28.3503C122.975 28.6706 122.11 28.8367 121.137 28.8367ZM121.137 26.7134C121.73 26.7134 122.252 26.5829 122.691 26.3338C123.13 26.0847 123.486 25.7525 123.77 25.3492C124.055 24.9459 124.257 24.4833 124.399 23.9732C124.529 23.4632 124.601 22.9413 124.601 22.4075C124.601 21.8855 124.529 21.3755 124.399 20.8535C124.268 20.3316 124.055 19.8809 123.77 19.4776C123.486 19.0743 123.13 18.754 122.691 18.5049C122.252 18.2558 121.73 18.1253 121.137 18.1253C120.544 18.1253 120.022 18.2558 119.583 18.5049C119.144 18.754 118.788 19.0861 118.503 19.4776C118.219 19.8809 118.017 20.3316 117.875 20.8535C117.744 21.3755 117.673 21.8855 117.673 22.4075C117.673 22.9413 117.744 23.4632 117.875 23.9732C118.005 24.4833 118.219 24.9459 118.503 25.3492C118.788 25.7525 119.144 26.0847 119.583 26.3338C120.022 26.5947 120.544 26.7134 121.137 26.7134ZM128.064 16.3341H130.093V12.6806H132.774V16.3341H135.193V18.3388H132.774V24.8392C132.774 25.1239 132.785 25.3611 132.809 25.5746C132.833 25.7763 132.892 25.9542 132.975 26.0965C133.058 26.2389 133.189 26.3456 133.367 26.4168C133.545 26.488 133.77 26.5236 134.078 26.5236C134.268 26.5236 134.458 26.5236 134.648 26.5117C134.838 26.4998 135.027 26.4761 135.217 26.4287V28.5045C134.921 28.5401 134.624 28.5638 134.351 28.5994C134.067 28.635 133.782 28.6469 133.485 28.6469C132.774 28.6469 132.204 28.5757 131.777 28.4452C131.35 28.3147 131.006 28.1131 130.769 27.8521C130.52 27.5911 130.366 27.2709 130.271 26.8794C130.188 26.488 130.128 26.0372 130.116 25.539V18.3625H128.088V16.3341H128.064Z" | ||
fill="#191919" | ||
/> | ||
<path | ||
d="M32.9944 11.6959H20.7053L16.9094 0L13.1016 11.6959L0.8125 11.684L10.7648 18.9198L6.95707 30.6039L16.9094 23.3799L26.8498 30.6039L23.054 18.9198L32.9944 11.6959Z" | ||
fill="#00B67A" | ||
/> | ||
<path d="M23.9166 21.5648L23.0625 18.9196L16.918 23.3797L23.9166 21.5648Z" fill="#005128" /> | ||
</g> | ||
<defs> | ||
<clipPath id="clip0_1665_6714"> | ||
<rect width="134.374" height="33" fill="white" transform="translate(0.8125)" /> | ||
</clipPath> | ||
</defs> | ||
</svg> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import { NextResponse } from 'next/server' | ||
import { type TrustpilotData, EDGE_CONFIG_STORE_KEY } from '@/services/trustpilot/trustpilot.types' | ||
|
||
export const config = { | ||
runtime: 'edge', | ||
} | ||
|
||
const handler = async () => { | ||
try { | ||
const data = await fetchTrustpilotData() | ||
await persistTrustpilotData(data) | ||
return new NextResponse(null, { status: 200 }) | ||
} catch (error) { | ||
console.error(error) | ||
return new NextResponse(JSON.stringify({ error }), { status: 500 }) | ||
} | ||
} | ||
|
||
export default handler | ||
|
||
type JSONResponse = { | ||
score: { | ||
trustScore: number | ||
} | ||
numberOfReviews: { | ||
total: number | ||
} | ||
} | ||
|
||
async function fetchTrustpilotData(): Promise<TrustpilotData> { | ||
const hedvigBusinessUnitId = process.env.HEDVIG_BUSINESS_UNIT_ID | ||
if (!hedvigBusinessUnitId) { | ||
throw new Error('HEDVIG_BUSINESS_UNIT_ID is not configured') | ||
} | ||
|
||
const trustpilotApiKey = process.env.TRUSTPILOT_API_KEY | ||
if (!trustpilotApiKey) { | ||
throw new Error('`TRUSTPILOT_API_KEY` is not configured') | ||
} | ||
|
||
const response = await fetch( | ||
`https://api.trustpilot.com/v1/business-units/${hedvigBusinessUnitId}`, | ||
{ | ||
headers: { | ||
apiKey: trustpilotApiKey, | ||
}, | ||
}, | ||
) | ||
|
||
if (!response.ok) { | ||
throw new Error(`Failed to retrieve Trustpilot information: ${response.statusText}`) | ||
} | ||
|
||
const { score, numberOfReviews }: JSONResponse = await response.json() | ||
return { | ||
score: score.trustScore, | ||
totalReviews: numberOfReviews.total, | ||
} | ||
} | ||
|
||
async function persistTrustpilotData(value: TrustpilotData) { | ||
const manageApiUrl = process.env.EDGE_CONFIG_MANAGE_API_URL | ||
if (!manageApiUrl) { | ||
throw new Error('EDGE_CONFIG_MANAGE_API_URL not configured') | ||
} | ||
|
||
const manageApiToken = process.env.EDGE_CONFIG_MANAGE_API_TOKEN | ||
if (!manageApiToken) { | ||
throw new Error('EDGE_CONFIG_MANAGE_API_TOKEN not configured') | ||
} | ||
|
||
const response = await fetch(manageApiUrl, { | ||
method: 'PATCH', | ||
headers: { | ||
Authorization: `Bearer ${manageApiToken}`, | ||
'Content-type': 'application/json', | ||
}, | ||
body: JSON.stringify({ | ||
items: [ | ||
{ | ||
operation: 'upsert', | ||
key: EDGE_CONFIG_STORE_KEY, | ||
value: value, | ||
}, | ||
], | ||
}), | ||
}) | ||
|
||
if (response.ok) { | ||
console.log('Trustpilot info updated in Edge config') | ||
} else { | ||
throw new Error(`Failed to update Trustpilot info in Edge config: ${response.statusText}`) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { get as getFromConfig } from '@vercel/edge-config' | ||
import { atom, useAtomValue } from 'jotai' | ||
import { useHydrateAtoms } from 'jotai/utils' | ||
import { type TrustpilotData, EDGE_CONFIG_STORE_KEY } from './trustpilot.types' | ||
|
||
const trustpilotAtom = atom<TrustpilotData | null>(null) | ||
|
||
export const useTrustpilotData = () => { | ||
return useAtomValue(trustpilotAtom) | ||
} | ||
|
||
export const useHydrateTrustpilotData = (data: TrustpilotData) => { | ||
useHydrateAtoms([[trustpilotAtom, data] as const]) | ||
} | ||
|
||
export const fetchTrustpilotData = async () => { | ||
const data = await getFromConfig<TrustpilotData>(EDGE_CONFIG_STORE_KEY) | ||
|
||
if (!data) { | ||
throw new Error('Failed to retrieve Trustpilot data from edge config') | ||
} | ||
|
||
return data | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
export const EDGE_CONFIG_STORE_KEY = 'trustpilot' | ||
|
||
export type TrustpilotData = { | ||
score: number | ||
totalReviews: number | ||
} |
Oops, something went wrong.