From 5f9f82ce0ed02b86a7bf6ddb5106e223ea8149d0 Mon Sep 17 00:00:00 2001 From: Alexandra Goff Date: Thu, 27 Jun 2024 15:49:17 -0700 Subject: [PATCH] [C] breadcrumbs and related content --- components/dynamic/DataProductsList/index.js | 65 +++++++++++++++++++ components/page/Aside/styles.js | 6 +- components/page/PageContent/index.js | 4 +- components/page/PageContent/styles.js | 47 +++++++++----- components/templates/DataProductPage/index.js | 31 ++++++++- components/templates/NewsPage/styles.js | 16 +++-- components/templates/StaffPage/index.js | 5 +- components/templates/StaffPage/styles.js | 8 ++- lib/api/entries.js | 27 +++++--- lib/api/fragments/data-product.js | 2 +- lib/localeStrings/en.json | 1 + 11 files changed, 170 insertions(+), 42 deletions(-) create mode 100644 components/dynamic/DataProductsList/index.js diff --git a/components/dynamic/DataProductsList/index.js b/components/dynamic/DataProductsList/index.js new file mode 100644 index 00000000..6fd00306 --- /dev/null +++ b/components/dynamic/DataProductsList/index.js @@ -0,0 +1,65 @@ +import PropTypes from "prop-types"; +import { useTranslation } from "react-i18next"; +import { Grid } from "@rubin-epo/epo-react-lib"; +import DataList from "@/dynamic/DataList"; +import Tile from "@/atomic/Tile"; +import { makeTruncatedString } from "@/lib/utils"; + +const DataProductsList = ({ + component, + excludeId = null, + header, + limit = 15, + button, + isWide = false, + isRelatedList = false, +}) => { + const { t } = useTranslation(); + const cols = limit === 4 ? 4 : 3; + + return ( + + {({ entries }) => ( + <> + {entries?.length > 0 && ( + + {entries.map(({ id, description, image, title, uri }) => ( + + ))} + + )} + + )} + + ); +}; + +DataProductsList.propTypes = { + component: PropTypes.string, + excludeId: PropTypes.string, + limit: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + header: PropTypes.string, + button: PropTypes.object, + isWide: PropTypes.bool, + isRelatedList: PropTypes.bool, +}; + +export default DataProductsList; diff --git a/components/page/Aside/styles.js b/components/page/Aside/styles.js index 1ce378e8..26d94d3b 100644 --- a/components/page/Aside/styles.js +++ b/components/page/Aside/styles.js @@ -12,10 +12,11 @@ export const Aside = styled.aside` flex-shrink: 0; flex-wrap: wrap; gap: var(--size-gap-aside); - margin-block-start: min(4.25vw, 64px); + padding: 0; + margin: 0; & a { - font-size: 65%; + font-size: 14px; color: var(--color-background-accent-aside); text-decoration: none; @@ -39,6 +40,7 @@ export const Aside = styled.aside` @media screen and (min-width: ${token("BREAK_DESKTOP_SMALL")}) { flex-direction: column; gap: 0; + padding: var(--PADDING_LARGE) 0 var(--PADDING_LARGE) 10px; > * + * { margin-block-start: 1em; diff --git a/components/page/PageContent/index.js b/components/page/PageContent/index.js index 050c2f7a..a56fb9c6 100644 --- a/components/page/PageContent/index.js +++ b/components/page/PageContent/index.js @@ -22,7 +22,7 @@ function PageContent({ {innerHero} )} - +
{children}
{sidebar}
@@ -38,7 +38,7 @@ function PageContent({ {innerHero} )} - + {children} {sidebar} diff --git a/components/page/PageContent/styles.js b/components/page/PageContent/styles.js index 408f79ab..053e8ce4 100644 --- a/components/page/PageContent/styles.js +++ b/components/page/PageContent/styles.js @@ -8,8 +8,9 @@ import { tokens, PADDING_LARGE, } from "@/styles/globalStyles"; +import { token } from "@rubin-epo/epo-react-lib"; -const WIDE_BREAKPOINT = "1125px"; +const WIDE_BREAKPOINT = token("BREAK_DESKTOP_SMALL"); const NARROW_BREAKPOINT = "800px"; const MOBILE_BREAKPOINT = "475px"; const HERO_OVERLAP = "clamp(-150px, -10vw, -80px)"; @@ -28,32 +29,46 @@ export const Hero = styled(HeroComponent)` `; export const FullLayout = styled.article` - ${({ $hasSidebar }) => - $hasSidebar - ? ` - display: flex; - ${containerRegular()}` - : ``} - - ${respond(`display: block;`, WIDE_BREAKPOINT)} + &[data-sidebar="false"] { + display: block; + } + + &[data-sidebar="true"] { + display: flex; + flex-direction: column; + ${containerRegular()} + } + + @media screen and (min-width: ${WIDE_BREAKPOINT}) { + &[data-sidebar="true"] { + flex-direction: row; + } + } `; export const OverlapLayout = styled.article` --hero-overlap: ${HERO_OVERLAP}; - display: flex; - ${({ $hasSidebar }) => - $hasSidebar - ? containerRegular() - : ` + &[data-sidebar="false"] { + display: block; ${containerNarrow()} max-width: calc(var(--max-width) + 2 * ${MAIN_INLINE_PADDING}); - `} + } - ${respond(`display: block;`, WIDE_BREAKPOINT)} + &[data-sidebar="true"] { + display: flex; + flex-direction: column; + ${containerRegular()} + } ${respond(`padding-inline: 0;`, NARROW_BREAKPOINT)} + @media screen and (min-width: ${WIDE_BREAKPOINT}) { + &[data-sidebar="true"] { + flex-direction: row; + } + } + &:last-child { padding-block-end: ${PADDING_LARGE}; } diff --git a/components/templates/DataProductPage/index.js b/components/templates/DataProductPage/index.js index 60c5ec63..178d3299 100644 --- a/components/templates/DataProductPage/index.js +++ b/components/templates/DataProductPage/index.js @@ -1,29 +1,43 @@ import PropTypes from "prop-types"; +import { useTranslation } from "react-i18next"; import { Container } from "@rubin-epo/epo-react-lib"; +import { useCustomBreadcrumbs } from "@/lib/utils"; import Body from "@/global/Body"; import PageContent from "@/page/PageContent"; import MediaAside from "@/components/page/Aside/patterns/Media"; import ContentBlockFactory from "@/factories/ContentBlockFactory"; +import DataProductsList from "@/components/dynamic/DataProductsList"; +import Breadcrumbs from "@/page/Breadcrumbs"; const DataProductPage = ({ data: { id, + uri, title, description, - typeHandle, - siteHandle, featuredImage = [], sidebarAssets = [], contentBlocks = [], }, }) => { + const { t } = useTranslation(); + const bodyProps = { description, featuredImage, title, }; + const pageLink = { + id, + uri, + title, + }; + const breadcrumbs = useCustomBreadcrumbs("For Scientists"); + const backPage = breadcrumbs[breadcrumbs.length - 1]; + return ( + } + footer={ + + } >

{title}

diff --git a/components/templates/NewsPage/styles.js b/components/templates/NewsPage/styles.js index d96f862c..a901ba13 100644 --- a/components/templates/NewsPage/styles.js +++ b/components/templates/NewsPage/styles.js @@ -8,7 +8,7 @@ import { tokens, } from "@/styles/globalStyles"; import { aHidden } from "@/styles/mixins/appearance"; -import { IconComposer, Image } from "@rubin-epo/epo-react-lib"; +import { IconComposer, Image, token } from "@rubin-epo/epo-react-lib"; export const Hero = styled.div` ${containerFullBleed("CONTAINER_FULL")} @@ -69,12 +69,9 @@ export const Article = styled.article` export const NewsDetail = styled.div` ${containerFullBleed("CONTAINER_REGULAR")} display: grid; - ${(props) => - props.$showAside - ? "grid-template-columns: minmax(75%, 1fr) minmax(25%, 250px)" - : "grid-template-columns: 1fr"}; + grid-template-columns: 1fr; + ${respond(`${containerWide()}`, "1360px")} - ${respond(`grid-template-columns: 1fr;`)} ${(props) => props.$showAside && `${Article} > section > div { @@ -96,6 +93,13 @@ export const NewsDetail = styled.div` } } `} + + @media screen and (min-width: ${token("BREAK_DESKTOP_SMALL")}) { + ${(props) => + props.$showAside + ? "grid-template-columns: minmax(75%, 1fr) minmax(25%, 250px)" + : "grid-template-columns: 1fr"}; + } `; export const Pretitle = styled.div` diff --git a/components/templates/StaffPage/index.js b/components/templates/StaffPage/index.js index c6a0dd98..f8e0efb8 100644 --- a/components/templates/StaffPage/index.js +++ b/components/templates/StaffPage/index.js @@ -11,7 +11,6 @@ import Breadcrumbs from "@/page/Breadcrumbs"; import PageContent from "@/page/PageContent"; import * as Styled from "./styles"; import Aside from "@/components/page/Aside"; -import AsideSection from "@/components/page/Aside/Section"; function getParentUri(uri) { const pathFragments = uri.split("/"); @@ -77,11 +76,11 @@ export default function StaffPage({ {...{ tags }} > {tradingCard?.[0] && ( - + - + )} } diff --git a/components/templates/StaffPage/styles.js b/components/templates/StaffPage/styles.js index a2863148..a82e4e48 100644 --- a/components/templates/StaffPage/styles.js +++ b/components/templates/StaffPage/styles.js @@ -1,9 +1,15 @@ import styled from "styled-components"; import { fluidScale, respond, containerRegular } from "@/styles/globalStyles"; +import AsideSection from "@/components/page/Aside/Section"; +import { token } from "@rubin-epo/epo-react-lib"; -const WIDE_BREAKPOINT = "1125px"; +const WIDE_BREAKPOINT = token("BREAK_DESKTOP_SMALL"); const MOBILE_BREAKPOINT = "475px"; +export const TradingCardSection = styled(AsideSection)` + max-width: var(--size-width-aside); +`; + export const QuotePositioner = styled.div` position: absolute; inset-block-start: calc(50% - var(--hero-overlap) * -0.5); diff --git a/lib/api/entries.js b/lib/api/entries.js index 53da9daf..3fd692ad 100644 --- a/lib/api/entries.js +++ b/lib/api/entries.js @@ -12,6 +12,7 @@ import { glossaryTermFragment } from "@/lib/api/fragments/glossary-term"; import { studentPageFragment } from "./fragments/student-page"; import { educatorPageFragment } from "./fragments/educator-page"; import { investigationLandingPageFragment } from "./fragments/investigation-landing-page"; +import { dataProductFragment } from "@/lib/api/fragments/data-product"; function dataListQueryify(fragment) { return gql` @@ -28,15 +29,15 @@ function dataListQueryify(fragment) { $date: [QueryArgument] ) { entries ( - id: ["not", $excludeId], - section: $section, - site: $site, - relatedTo: $relatedTo, - limit: $limit, - offset: $offset, - orderBy: $orderBy, - inReverse: $inReverse, - search: $search, + id: ["not", $excludeId], + section: $section, + site: $site, + relatedTo: $relatedTo, + limit: $limit, + offset: $offset, + orderBy: $orderBy, + inReverse: $inReverse, + search: $search, date: $date) { ${fragment} } @@ -227,6 +228,14 @@ export function useDataList({ ${dataListQueryify(`...slideshowFragment`)} `; break; + case "dataProducts": + theSection = section; + theOrderBy = "dateCreated desc"; + query = gql` + ${dataProductFragment} + ${dataListQueryify(`...dataProductFragment`)} + `; + break; default: // find a way to pass just news and pages theSection = null; theOrderBy = "dateUpdated desc"; diff --git a/lib/api/fragments/data-product.js b/lib/api/fragments/data-product.js index c310c602..36c01339 100644 --- a/lib/api/fragments/data-product.js +++ b/lib/api/fragments/data-product.js @@ -9,7 +9,7 @@ export const dataProductFragment = ` ...on dataProducts_dataProduct_Entry { dateCreated description - featuredImage { + image: featuredImage { ...on contentImages_Asset { ${getImageFields("crop", 900, 550)} } diff --git a/lib/localeStrings/en.json b/lib/localeStrings/en.json index b0378093..4dbbaa33 100644 --- a/lib/localeStrings/en.json +++ b/lib/localeStrings/en.json @@ -29,6 +29,7 @@ "toggle-nav": "Toggle navigation menu", "toggle-search": "Toggle search", "homepage": "Homepage", + "back": "Back", "contact-form": { "contact-us": "Contact us", "success": "Thank you. We’ve received your message.",