From 0af9cb87d9cab0f58260e5b9d78dfbab3cd8906a Mon Sep 17 00:00:00 2001 From: Jeff Reiffers Date: Mon, 27 Nov 2023 09:15:03 +0100 Subject: [PATCH] feat: add generic strapi fancy article page --- src/app/app.jsx | 3 + src/config.js | 1 + src/constants/constants.js | 1 + src/pages/cms-information-page/index.tsx | 4 +- src/pages/cms-transport-page/index.tsx | 4 +- .../fancy-article-page.tsx | 84 +++++++++ src/pages/fancy-article-page-v2/styled.ts | 172 ++++++++++++++++++ src/routes.ts | 2 + 8 files changed, 267 insertions(+), 4 deletions(-) create mode 100644 src/pages/fancy-article-page-v2/fancy-article-page.tsx create mode 100644 src/pages/fancy-article-page-v2/styled.ts diff --git a/src/app/app.jsx b/src/app/app.jsx index ed537b466..a2a504910 100644 --- a/src/app/app.jsx +++ b/src/app/app.jsx @@ -35,6 +35,7 @@ import { PATHNAME_EVENTS, PATHNAME_NEWS_ARTICLE, PATHNAME_NEWS_ARTICLE_V2, + PATHNAME_FANCY_ARTICLE_V2, PATHNAME_REPORTS, PATHNAME_ABOUT, PATHNAME_ABOUT_REGISTRATION, @@ -64,6 +65,7 @@ import '../assets/css/bootstrap-override.scss'; import { NewsArticle } from '../pages/news-article-page/news-article-page'; import { NewsArchivePage } from '../pages/news-archive-page/news-archive-page'; import { NewsArticlePageV2 } from '../pages/news-article-page-v2/news-article-page'; +import { FancyArticlePageV2 } from '../pages/fancy-article-page-v2/fancy-article-page'; import { CmsArticlePage } from '../pages/cms-article-page/cms-article-page'; import OrganizationsRouter from '../pages/organizations'; import InformationPage from '../pages/cms-information-page'; @@ -113,6 +115,7 @@ export function App({ language, onChangeLanguage }) { [`${PATHNAME_EVENTS}/:eventId`]: EventDetailsPage, [`${PATHNAME_NEWS_ARTICLE}/:id`]: NewsArticle, [`${PATHNAME_NEWS_ARTICLE_V2}/:id`]: NewsArticlePageV2, + [`${PATHNAME_FANCY_ARTICLE_V2}/:id`]: FancyArticlePageV2, [PATHNAME_REPORTS]: ReportPage, [PATHNAME_ABOUT]: CmsArticlePage, [PATHNAME_ABOUT_REGISTRATION]: CmsArticlePage, diff --git a/src/config.js b/src/config.js index e5b070a3c..6a792284a 100644 --- a/src/config.js +++ b/src/config.js @@ -11,6 +11,7 @@ const env = window.env || { // env.SEARCH_HOST = 'https://staging.fellesdatakatalog.digdir.no'; // env.SEARCH_FULLTEXT_HOST = 'https://search.staging.fellesdatakatalog.digdir.no'; // env.CMS_API_HOST = 'https://cms-fellesdatakatalog.digdir.no'; +// env.FDK_CMS_BASE_URI = 'https://cms.staging.fellesdatakatalog.digdir.no'; // env.ORGANIZATION_HOST = // 'https://organization-bff.staging.fellesdatakatalog.digdir.no'; // env.ORGANIZATION_CATALOG_URI = diff --git a/src/constants/constants.js b/src/constants/constants.js index 42446559c..32129f4bc 100644 --- a/src/constants/constants.js +++ b/src/constants/constants.js @@ -13,6 +13,7 @@ export const PATHNAME_EVENTS = '/events'; export const PATHNAME_REPORTS = '/reports'; export const PATHNAME_ABOUT = '/about'; export const PATHNAME_ABOUT_REGISTRATION = '/about-registration'; +export const PATHNAME_FANCY_ARTICLE_V2 = '/fancy-article-v2'; export const PATHNAME_NEWS_ARTICLE = '/news'; export const PATHNAME_NEWS_ARTICLE_V2 = '/news-v2'; export const PATHNAME_NEWS_ARCHIVE = '/news-archive'; diff --git a/src/pages/cms-information-page/index.tsx b/src/pages/cms-information-page/index.tsx index 717f473d1..1cf36b05d 100644 --- a/src/pages/cms-information-page/index.tsx +++ b/src/pages/cms-information-page/index.tsx @@ -4,7 +4,6 @@ import { RouteComponentProps, withRouter } from 'react-router-dom'; import { ThemeProvider } from 'styled-components'; import { CircularProgress } from '@mui/material'; -import env from '../../env'; import localization from '../../lib/localization'; import { useGetFancyArticleQuery } from '../../api/generated/cms/graphql'; @@ -24,10 +23,11 @@ import { themeFDK } from '../../app/theme'; import { Entity } from '../../types/enums'; import SC from './styled'; +import { getConfig } from '../../config'; interface Props extends RouteComponentProps {} -const { FDK_CMS_BASE_URI } = env; +const FDK_CMS_BASE_URI = getConfig().cmsV2Api.host; const articleIds: { [pathname: string]: string } = { [PATHNAME_ABOUT_DATASETS]: '7', diff --git a/src/pages/cms-transport-page/index.tsx b/src/pages/cms-transport-page/index.tsx index 28a1afea0..5702393f9 100644 --- a/src/pages/cms-transport-page/index.tsx +++ b/src/pages/cms-transport-page/index.tsx @@ -4,7 +4,6 @@ import { RouteComponentProps, withRouter } from 'react-router-dom'; import { ThemeProvider } from 'styled-components'; import { CircularProgress } from '@mui/material'; -import env from '../../env'; import localization from '../../lib/localization'; import { useGetTransportArticleQuery } from '../../api/generated/cms/graphql'; @@ -35,10 +34,11 @@ import { themeNAP } from '../../app/theme'; import SC from './styled'; import YoutubeEmbed from '../../components/youtube-embed'; import { Entity } from '../../types/enums'; +import { getConfig } from '../../config'; interface Props extends RouteComponentProps {} -const { FDK_CMS_BASE_URI } = env; +const FDK_CMS_BASE_URI = getConfig().cmsV2Api.host; const articleIds: { [pathname: string]: string } = { [PATHNAME_TRANSPORT_GENERAL]: '2', diff --git a/src/pages/fancy-article-page-v2/fancy-article-page.tsx b/src/pages/fancy-article-page-v2/fancy-article-page.tsx new file mode 100644 index 000000000..bfe9b9450 --- /dev/null +++ b/src/pages/fancy-article-page-v2/fancy-article-page.tsx @@ -0,0 +1,84 @@ +import React, { FC, memo } from 'react'; +import { useParams } from 'react-router-dom'; +import { compose } from 'redux'; +import { CircularProgress } from '@mui/material'; +import { useGetFancyArticleQuery } from '../../api/generated/cms/graphql'; +import ErrorPage from '../error-page'; +import withErrorBoundary from '../../components/with-error-boundary'; +import localization from '../../lib/localization'; +import SC from './styled'; +import Markdown from '../../components/markdown'; +import { + isBasicImage, + isBasicParagraph, + isBasicYoutube +} from '../../lib/strapi'; +import YoutubeEmbed from '../../components/youtube-embed'; +import { getConfig } from '../../config'; + +const FDK_CMS_BASE_URI = getConfig().cmsV2Api.host; + +const FancyArticlePage: FC = () => { + const { id } = useParams<{ id: string }>(); + + const { data, loading, error } = useGetFancyArticleQuery({ + variables: { id } + }); + + if (loading) { + return ( + + + + ); + } + + if (error?.name !== undefined || !data || !data.fancyArticle) { + return ; + } + + const { + fancyArticle: { data: fancyArticleEntity } + } = data; + + const fancyArticle = fancyArticleEntity?.attributes; + + return ( +
+ {fancyArticle && ( + + {fancyArticle.title} + {fancyArticle.subtitle} + {fancyArticle.Content?.map( + component => + (isBasicParagraph(component) && ( + + {component?.Content ?? ''} + + )) || + (isBasicImage(component) && ( + + + {component?.media?.data?.attributes?.caption && ( + + {localization.informationPage.imageText} + {component?.media?.data?.attributes?.caption} + + )} + + )) || + (isBasicYoutube(component) && ( + + )) + )} + + )} +
+ ); +}; + +const enhance = compose(withErrorBoundary(ErrorPage)); +export const FancyArticlePageV2 = enhance(memo(FancyArticlePage)); diff --git a/src/pages/fancy-article-page-v2/styled.ts b/src/pages/fancy-article-page-v2/styled.ts new file mode 100644 index 000000000..0a17b3ff3 --- /dev/null +++ b/src/pages/fancy-article-page-v2/styled.ts @@ -0,0 +1,172 @@ +import styled from 'styled-components'; + +import { Colour, theme, Unit } from '@fellesdatakatalog/theme'; +import { Backdrop as MuiBackdrop } from '@mui/material'; +import SideMenuBase from '../../components/side-menu'; + +import HamburgerIconBase from '../../images/hamburger-menu-stroke.svg'; + +const onMobileView = '@media (max-width: 900px)'; +const customBreakingPoint = '@media (max-width: 992px)'; + +const InformationPage = styled.article` + background-color: ${({ theme: t }) => t.lighter}; + display: flex; + gap: ${theme.spacing('S16', Unit.EM)}; + word-break: break-word; + + ${customBreakingPoint} { + && { + max-width: fit-content; + } + } + + ${onMobileView} { + flex-direction: column; + } +`; + +const Aside = styled.aside` + display: flex; + flex: 0 0 20%; + flex-direction: column; + + ${onMobileView} { + flex: 1; + } +`; + +const Article = styled.main` + display: flex; + flex-direction: column; + gap: ${theme.spacing('S10')}; + z-index: 5; +`; + +const Title = styled.h1` + font-size: ${theme.fontSize('FS48', Unit.REM)}; + font-weight: ${theme.fontWeight('FW700')}; + padding-left: 0; +`; + +const Description = styled.p` + font-size: ${theme.fontSize('FS20')}; +`; + +const Content = styled.p` + & > div { + & > h2 { + border-bottom: 1px solid ${({ theme: t }) => t.light}; + font-size: ${theme.fontSize('FS32', Unit.REM)}; + font-weight: ${theme.fontWeight('FW700')}; + padding: ${theme.spacing('S6')}; + padding-left: 0; + margin-bottom: ${theme.spacing('S10', Unit.EM)}; + margin-top: ${theme.spacing('S48')}; + } + } + + & a { + text-decoration: underline; + } +`; + +const ImageWrapper = styled.div` + margin-bottom: ${theme.spacing('S16')}; +`; + +const Image = styled.img` + max-width: 100%; +`; + +const ImageText = styled.span` + font-size: ${theme.fontSize('FS14', Unit.REM)}; +`; + +const SideMenu = styled(SideMenuBase)` + min-width: 260px; + ${onMobileView} { + display: none; + width: auto; + margin-right: 0; + } +`; + +const SideMenuSmall = styled(SideMenuBase)` + display: none; + ${onMobileView} { + display: flex; + flex: 1; + ul { + flex: 1; + li { + background-color: ${({ theme: t }) => t.extendedColors.neutralLighter}; + border-radius: 5px; + margin-top: 2px; + margin-bottom: 2px; + + a { + background-color: transparent !important; + color: ${({ theme: t }) => t.dark}; + margin-left: 20px; + &.active { + color: ${({ theme: t }) => t.dark} !important; + } + } + } + } + } +`; + +const MenuToggle = styled.button` + display: none; + color: ${({ theme: t }) => t.dark}; + + ${onMobileView} { + display: flex; + justify-content: center; + align-items: center; + padding: 13px; + border-radius: 5px; + font-size: ${theme.fontSize('FS16', Unit.REM)}; + border: none; + background-color: ${({ theme: t }) => t.light}; + } + + &:hover { + color: ${({ theme: t }) => t.darker}; + } + + &:active { + background: black; + color: ${({ theme: t }) => t.lighter}; + } +`; + +const Backdrop = styled(MuiBackdrop)` + color: ${theme.colour(Colour.NEUTRAL, 'N0')}; + z-index: ${theme.colour(Colour.NEUTRAL, 'N0')} + 1; +`; + +const HamburgerIcon = styled(HamburgerIconBase)` + width: 20px; + height: 20px; + margin-right: 0.5em; +`; + +export default { + InformationPage, + Aside, + Article, + Title, + Description, + Content, + ImageWrapper, + Image, + ImageText, + SideMenu, + SideMenuSmall, + MenuToggle, + Backdrop, + HamburgerIcon +}; diff --git a/src/routes.ts b/src/routes.ts index 4c1d2a843..23aff47be 100644 --- a/src/routes.ts +++ b/src/routes.ts @@ -13,6 +13,7 @@ import { PATHNAME_NEWS_ARTICLE, PATHNAME_NEWS_ARTICLE_V2, PATHNAME_NEWS_ARCHIVE, + PATHNAME_FANCY_ARTICLE_V2, PATHNAME_GUIDANCE, PATHNAME_GUIDANCE_METADATA, PATHNAME_ORGANIZATIONS, @@ -60,6 +61,7 @@ const routes: any = { `${PATHNAME_EVENTS}/:eventId`, `${PATHNAME_NEWS_ARTICLE}/:id`, `${PATHNAME_NEWS_ARTICLE_V2}/:id`, + `${PATHNAME_FANCY_ARTICLE_V2}/:id`, PATHNAME_REPORTS, PATHNAME_ABOUT, PATHNAME_ABOUT_REGISTRATION,