From ce857e252baca96fbfb15643e218485824873e3f Mon Sep 17 00:00:00 2001 From: Daniel Dimitrov Date: Mon, 16 Sep 2024 16:26:09 +0200 Subject: [PATCH] fix: display last updated version in cookie banner The cookie banner now shows the last updated version. In addition to this it is no longer necessary to update the version number inside of the store slice. We can control it from the frontmatter of the terms.md doc. Whenever the version gets updated the cookie banner is going to pop up. --- next.config.mjs | 8 +- package.json | 12 +-- .../common/CookieAndTermBanner/index.tsx | 12 ++- src/markdown/terms/terms.md | 5 ++ src/markdown/terms/terms.md.d.ts | 5 ++ src/store/cookiesAndTermsSlice.ts | 12 ++- yarn.lock | 73 +++++++++++++++++++ 7 files changed, 115 insertions(+), 12 deletions(-) create mode 100644 src/markdown/terms/terms.md.d.ts diff --git a/next.config.mjs b/next.config.mjs index 5bf99b3aea..b867dc0049 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -4,6 +4,8 @@ import withPWAInit from '@ducanh2912/next-pwa' import remarkGfm from 'remark-gfm' import remarkHeadingId from 'remark-heading-id' import createMDX from '@next/mdx' +import remarkFrontmatter from 'remark-frontmatter' +import remarkMdxFrontmatter from 'remark-mdx-frontmatter' const SERVICE_WORKERS_PATH = './src/service-workers' @@ -82,8 +84,12 @@ const nextConfig = { } const withMDX = createMDX({ extension: /\.(md|mdx)?$/, + jsx: true, options: { - remarkPlugins: [remarkHeadingId, remarkGfm], + remarkPlugins: [ + remarkFrontmatter, + [remarkMdxFrontmatter, { name: 'metadata' }], + remarkHeadingId, remarkGfm], rehypePlugins: [], }, }) diff --git a/package.json b/package.json index 71b43e9c66..6ca3cd683f 100644 --- a/package.json +++ b/package.json @@ -50,12 +50,9 @@ "@emotion/server": "^11.11.0", "@emotion/styled": "^11.11.0", "@gnosis.pm/zodiac": "^4.0.3", - "@mdx-js/loader": "^3.0.1", - "@mdx-js/react": "^3.0.1", "@mui/icons-material": "^5.14.20", "@mui/material": "^5.14.20", "@mui/x-date-pickers": "^5.0.20", - "@next/mdx": "^14.2.11", "@reduxjs/toolkit": "^2.2.6", "@safe-global/api-kit": "^2.4.4", "@safe-global/protocol-kit": "^4.1.0", @@ -65,7 +62,6 @@ "@safe-global/safe-modules-deployments": "^2.2.1", "@sentry/react": "^7.91.0", "@spindl-xyz/attribution-lite": "^1.4.0", - "@types/mdx": "^2.0.13", "@walletconnect/utils": "^2.16.1", "@walletconnect/web3wallet": "^1.15.1", "@web3-onboard/coinbase": "^2.2.6", @@ -96,7 +92,6 @@ "react-papaparse": "^4.0.2", "react-redux": "^9.1.2", "remark-gfm": "^4.0.0", - "remark-heading-id": "^1.0.1", "semver": "^7.6.3", "zodiac-roles-deployments": "^2.2.5" }, @@ -104,7 +99,10 @@ "@chromatic-com/storybook": "^1.3.1", "@cowprotocol/app-data": "^2.1.0", "@faker-js/faker": "^8.1.0", + "@mdx-js/loader": "^3.0.1", + "@mdx-js/react": "^3.0.1", "@next/bundle-analyzer": "^13.5.6", + "@next/mdx": "^14.2.11", "@openzeppelin/contracts": "^4.9.6", "@safe-global/safe-core-sdk-types": "^5.0.1", "@sentry/types": "^7.74.0", @@ -127,6 +125,7 @@ "@types/jest": "^29.5.4", "@types/js-cookie": "^3.0.6", "@types/lodash": "^4.14.182", + "@types/mdx": "^2.0.13", "@types/node": "18.11.18", "@types/qrcode": "^1.5.5", "@types/react": "^18.3.4", @@ -152,6 +151,9 @@ "jest-environment-jsdom": "^29.6.2", "mockdate": "^3.0.5", "prettier": "^2.7.0", + "remark-frontmatter": "^5.0.0", + "remark-heading-id": "^1.0.1", + "remark-mdx-frontmatter": "^5.0.0", "storybook": "^8.3.0", "ts-prune": "^0.10.3", "typechain": "^8.3.2", diff --git a/src/components/common/CookieAndTermBanner/index.tsx b/src/components/common/CookieAndTermBanner/index.tsx index b9b6a5fbb1..f13100f888 100644 --- a/src/components/common/CookieAndTermBanner/index.tsx +++ b/src/components/common/CookieAndTermBanner/index.tsx @@ -4,6 +4,7 @@ import type { CheckboxProps } from '@mui/material' import { Grid, Button, Checkbox, FormControlLabel, Typography, Paper, SvgIcon, Box } from '@mui/material' import WarningIcon from '@/public/images/notifications/warning.svg' import { useForm } from 'react-hook-form' +import { metadata } from '@/markdown/terms/terms.md' import { useAppDispatch, useAppSelector } from '@/store' import { selectCookies, CookieAndTermType, saveCookieAndTermConsent } from '@/store/cookiesAndTermsSlice' @@ -18,6 +19,7 @@ const COOKIE_AND_TERM_WARNING: Record = { [CookieAndTermType.NECESSARY]: '', [CookieAndTermType.UPDATES]: `You attempted to open the "What's new" section but need to accept the "Beamer" cookies first.`, [CookieAndTermType.ANALYTICS]: '', + [CookieAndTermType.VERSION]: '', } const CookieCheckbox = ({ @@ -47,6 +49,7 @@ export const CookieAndTermBanner = ({ [CookieAndTermType.NECESSARY]: true, [CookieAndTermType.UPDATES]: cookies[CookieAndTermType.UPDATES] ?? false, [CookieAndTermType.ANALYTICS]: cookies[CookieAndTermType.ANALYTICS] ?? false, + [CookieAndTermType.VERSION]: metadata.version, ...(warningKey ? { [warningKey]: true } : {}), }, }) @@ -75,9 +78,10 @@ export const CookieAndTermBanner = ({ By browsing this page, you accept our{' '} - Terms & Conditions (last updated August 2024) and the - use of necessary cookies. By clicking "Accept all" you additionally agree to the use of Beamer - and Analytics cookies as listed below. Cookie policy + Terms & Conditions (last updated{' '} + {metadata.last_update_date}) and the use of necessary cookies. By clicking "Accept all" you + additionally agree to the use of Beamer and Analytics cookies as listed below.{' '} + Cookie policy @@ -140,7 +144,7 @@ const CookieBannerPopup = (): ReactElement | null => { const dispatch = useAppDispatch() // Open the banner if cookie preferences haven't been set - const shouldOpen = cookies[CookieAndTermType.NECESSARY] === undefined + const shouldOpen = cookies[CookieAndTermType.VERSION] !== metadata.version useEffect(() => { if (shouldOpen) { diff --git a/src/markdown/terms/terms.md b/src/markdown/terms/terms.md index 6e6564b8ed..e0b9433cbf 100644 --- a/src/markdown/terms/terms.md +++ b/src/markdown/terms/terms.md @@ -1,3 +1,8 @@ +--- +version: 1.2 +last_update_date: September, 2024 +--- + # Terms and Conditions Last updated: September, 2024 diff --git a/src/markdown/terms/terms.md.d.ts b/src/markdown/terms/terms.md.d.ts new file mode 100644 index 0000000000..a89eca7930 --- /dev/null +++ b/src/markdown/terms/terms.md.d.ts @@ -0,0 +1,5 @@ +export { default } from '*.md' +export const metadata = { + version: string, + last_update_date: string, +} diff --git a/src/store/cookiesAndTermsSlice.ts b/src/store/cookiesAndTermsSlice.ts index b63d31fd07..80fdb854eb 100644 --- a/src/store/cookiesAndTermsSlice.ts +++ b/src/store/cookiesAndTermsSlice.ts @@ -7,19 +7,27 @@ export enum CookieAndTermType { NECESSARY = 'necessary', UPDATES = 'updates', ANALYTICS = 'analytics', + VERSION = 'version', } -export type CookiesAndTermsState = Record +export type CookiesAndTermsState = { + [CookieAndTermType.TERMS]: boolean | undefined + [CookieAndTermType.NECESSARY]: boolean | undefined + [CookieAndTermType.UPDATES]: boolean | undefined + [CookieAndTermType.ANALYTICS]: boolean | undefined + [CookieAndTermType.VERSION]: string | undefined +} const initialState: CookiesAndTermsState = { [CookieAndTermType.TERMS]: undefined, [CookieAndTermType.NECESSARY]: undefined, [CookieAndTermType.UPDATES]: undefined, [CookieAndTermType.ANALYTICS]: undefined, + [CookieAndTermType.VERSION]: undefined, } export const cookiesAndTermsSlice = createSlice({ - name: 'cookies_terms_v1.1', + name: `cookies_terms`, initialState, reducers: { saveCookieAndTermConsent: (_, { payload }: PayloadAction) => payload, diff --git a/yarn.lock b/yarn.lock index 2833b5d7de..31b482da3a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10239,6 +10239,13 @@ estree-util-to-js@^2.0.0: astring "^1.8.0" source-map "^0.7.0" +estree-util-value-to-estree@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/estree-util-value-to-estree/-/estree-util-value-to-estree-3.1.2.tgz#d2f0e5d350a6c181673eb7299743325b86a9bf5c" + integrity sha512-S0gW2+XZkmsx00tU2uJ4L9hUT7IFabbml9pHh2WQqFmAbxit++YGZne0sKJbNwkj9Wvg9E4uqWl4nCIFQMmfag== + dependencies: + "@types/estree" "^1.0.0" + estree-util-visit@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/estree-util-visit/-/estree-util-visit-2.0.0.tgz#13a9a9f40ff50ed0c022f831ddf4b58d05446feb" @@ -10803,6 +10810,13 @@ fastq@^1.6.0: dependencies: reusify "^1.0.4" +fault@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fault/-/fault-2.0.1.tgz#d47ca9f37ca26e4bd38374a7c500b5a384755b6c" + integrity sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ== + dependencies: + format "^0.2.0" + faye-websocket@0.11.4: version "0.11.4" resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" @@ -11073,6 +11087,11 @@ form-data@~2.3.2: combined-stream "^1.0.6" mime-types "^2.1.12" +format@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/format/-/format-0.2.2.tgz#d6170107e9efdc4ed30c9dc39016df942b5cb58b" + integrity sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww== + forwarded@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" @@ -13642,6 +13661,18 @@ mdast-util-from-markdown@^2.0.0: micromark-util-types "^2.0.0" unist-util-stringify-position "^4.0.0" +mdast-util-frontmatter@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/mdast-util-frontmatter/-/mdast-util-frontmatter-2.0.1.tgz#f5f929eb1eb36c8a7737475c7eb438261f964ee8" + integrity sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA== + dependencies: + "@types/mdast" "^4.0.0" + devlop "^1.0.0" + escape-string-regexp "^5.0.0" + mdast-util-from-markdown "^2.0.0" + mdast-util-to-markdown "^2.0.0" + micromark-extension-frontmatter "^2.0.0" + mdast-util-gfm-autolink-literal@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz#abd557630337bd30a6d5a4bd8252e1c2dc0875d5" @@ -13909,6 +13940,16 @@ micromark-core-commonmark@^2.0.0: micromark-util-symbol "^2.0.0" micromark-util-types "^2.0.0" +micromark-extension-frontmatter@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/micromark-extension-frontmatter/-/micromark-extension-frontmatter-2.0.0.tgz#651c52ffa5d7a8eeed687c513cd869885882d67a" + integrity sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg== + dependencies: + fault "^2.0.0" + micromark-util-character "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + micromark-extension-gfm-autolink-literal@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz#6286aee9686c4462c1e3552a9d505feddceeb935" @@ -16158,6 +16199,16 @@ relateurl@^0.2.7: resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" integrity sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog== +remark-frontmatter@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/remark-frontmatter/-/remark-frontmatter-5.0.0.tgz#b68d61552a421ec412c76f4f66c344627dc187a2" + integrity sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ== + dependencies: + "@types/mdast" "^4.0.0" + mdast-util-frontmatter "^2.0.0" + micromark-extension-frontmatter "^2.0.0" + unified "^11.0.0" + remark-gfm@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/remark-gfm/-/remark-gfm-4.0.0.tgz#aea777f0744701aa288b67d28c43565c7e8c35de" @@ -16178,6 +16229,18 @@ remark-heading-id@^1.0.1: lodash "^4.17.21" unist-util-visit "^1.4.0" +remark-mdx-frontmatter@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/remark-mdx-frontmatter/-/remark-mdx-frontmatter-5.0.0.tgz#22c48c4758963701595082fd89157586caa5a372" + integrity sha512-kI75pshe27TM71R+0iX7C3p4MbGMdygkvSbrk1WYSar88WAwR2JfQilofcDGgDNFAWUo5IwTPyq9XvGpifTwqQ== + dependencies: + "@types/mdast" "^4.0.0" + estree-util-is-identifier-name "^3.0.0" + estree-util-value-to-estree "^3.0.0" + toml "^3.0.0" + unified "^11.0.0" + yaml "^2.0.0" + remark-mdx@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/remark-mdx/-/remark-mdx-3.0.1.tgz#8f73dd635c1874e44426e243f72c0977cf60e212" @@ -17700,6 +17763,11 @@ toidentifier@1.0.1: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== +toml@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/toml/-/toml-3.0.0.tgz#342160f1af1904ec9d204d03a5d61222d762c5ee" + integrity sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w== + totalist@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/totalist/-/totalist-1.1.0.tgz#a4d65a3e546517701e3e5c37a47a70ac97fe56df" @@ -19121,6 +19189,11 @@ yaml@^1.10.0, yaml@^1.10.2: resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== +yaml@^2.0.0: + version "2.5.1" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.5.1.tgz#c9772aacf62cb7494a95b0c4f1fb065b563db130" + integrity sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q== + yargs-parser@^18.1.2: version "18.1.3" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0"