diff --git a/frontend/components/NewLayout/Common/CTALink.tsx b/frontend/components/NewLayout/Common/CTALink.tsx index a9558005f..3c08c438a 100644 --- a/frontend/components/NewLayout/Common/CTALink.tsx +++ b/frontend/components/NewLayout/Common/CTALink.tsx @@ -25,14 +25,14 @@ const Link = styled(MUILink)( &:hover, &:focus { text-decoration: underline; - ${LinkIcon} { + ${CTALinkIcon} { background-color: ${theme.palette.common.brand.main}; } } `, ) as EnhancedLink -const LinkIcon = styled("span")( +export const CTALinkIcon = styled("span")( ({ theme }) => ` align-items: center; background-color: ${theme.palette.common.brand.light}; @@ -59,13 +59,13 @@ const CTALink = (props: CTALinkProps) => { return ( {children} - + {isExternal ? ( ) : ( )} - + ) } diff --git a/frontend/components/NewLayout/Common/LinkBox.tsx b/frontend/components/NewLayout/Common/LinkBox.tsx new file mode 100644 index 000000000..539e6348a --- /dev/null +++ b/frontend/components/NewLayout/Common/LinkBox.tsx @@ -0,0 +1,174 @@ +import React from "react" + +import Image, { ImageProps } from "next/image" + +import { PropsOf } from "@emotion/react" +import { Typography } from "@mui/material" +import { styled } from "@mui/material/styles" + +import CTALink, { CTALinkIcon, CTALinkProps } from "./CTALink" +import { fontSize } from "/src/theme/util" + +const LinkBoxContainer = styled("article")( + ({ theme }) => ` + background-color: ${theme.palette.common.grayscale.backgroundBox}; + width: 100%; + display: flex; + flex-direction: column; + justify-content: space-between; + height: 100%; + position: relative; + + &:hover { + cursor: pointer; + + ${LinkBoxTitle} { + color: ${theme.palette.common.brand.main}; + text-decoration: underline; + } + ${LinkBoxLink} { + text-decoration: underline; + ${CTALinkIcon} { + background-color: ${theme.palette.common.brand.main}; + svg { + background-color: ${theme.palette.common.brand.main}; + } + } + } + } +`, +) + +const LinkBoxContent = styled("div")` + /* */ +` + +const LinkBoxImageContainer = styled("div")` + margin: 0; + display: flex; + justify-content: stretch; + min-height: 10rem; + position: relative; + + &:before { + content: ""; + display: block; + padding-top: calc(10 / 16) * 100%; + width: 100%; + } +` + +const LinkBoxImage = styled(Image)` + bottom: 0; + height: 100%; + left: 0; + object-fit: cover; + position: absolute; + right: 0; + top: 0; + width: 100%; +` + +const LinkBoxTitleImageContainer = styled("div")` + position: relative; + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; +` + +const LinkBoxTitleImage = styled(Image)` + object-fit: contain; + position: absolute; +` + +const LinkBoxTextContainer = styled("div")` + padding: 16px; +` + +const LinkBoxTitle = styled(Typography)( + ({ theme }) => ` + ${fontSize(21, 28)} + font-weight: 700; + color: ${theme.palette.common.brand.nearlyBlack}; + letter-spacing: -0.42px; + hyphens: auto; + word-break: break-word; + margin: 0 0 16px; + + ${theme.breakpoints.up("desktop")} { + ${fontSize(25, 32)} + letter-spacing: -0.5px; + } +`, +) + +const LinkBoxDescription = styled("p")( + ({ theme }) => ` + ${fontSize(15, 22)}; + color: ${theme.palette.common.grayscale.black}; + margin: 0; + + ${theme.breakpoints.up("desktop")} { + ${fontSize(17, 26)} + } +`, +) + +const LinkBoxLink = styled(CTALink)` + margin: 0 -8px 24px 0; + align-self: flex-end; + + span[aria-hidden="true"] { + position: absolute; + inset: 0; + } + + &:focus { + outline: none; + } +` as typeof CTALink + +export interface LinkBoxProps { + imageProps?: ImageProps + title: string + titleImageProps?: ImageProps + description?: string + linkProps: CTALinkProps +} + +const LinkBox = ({ + imageProps, + title, + description, + titleImageProps, + linkProps, + ...props +}: LinkBoxProps & PropsOf) => { + return ( + + + {imageProps && ( + + + + )} + + {titleImageProps ? ( + + + + ) : ( + {title} + )} + {description && ( + {description} + )} + + + + + ) +} + +export default LinkBox diff --git a/frontend/components/NewLayout/Common/LinkBoxList.tsx b/frontend/components/NewLayout/Common/LinkBoxList.tsx new file mode 100644 index 000000000..abdd34bff --- /dev/null +++ b/frontend/components/NewLayout/Common/LinkBoxList.tsx @@ -0,0 +1,78 @@ +import { PropsOf } from "@emotion/react" +import { styled } from "@mui/material/styles" + +import LinkBox, { LinkBoxProps } from "./LinkBox" + +const linkBoxListVariants = ["default", "wide"] as const + +export type LinkBoxListVariant = (typeof linkBoxListVariants)[number] + +const LinkBoxListContainer = styled("div")` + display: block; +` + +const LinkBoxListComponent = styled("ul")( + ({ theme }) => ` + padding: 0; + margin: 0; + list-style: none; + display: grid; + gap: 32px 0; + + :not(.wide) { + ${theme.breakpoints.up(768)} { + grid-template-columns: repeat(2, 1fr); + gap: 32px 24px; + } + ${theme.breakpoints.up("desktop")} { + grid-template-columns: repeat(3, 1fr); + } + ${theme.breakpoints.up(1920)} { + gap: 32px; + } + } + + .wide { + grid-template-columns: 2fr; + } +`, +) + +const Spacer = styled("div")( + ({ theme }) => ` + display: flex; + width: 100%; + margin-top: 1.75rem; + ${theme.breakpoints.up("md")} { + margin-top: 2rem; + } + ${theme.breakpoints.up("lg")} { + margin-top: 2.25rem; + } +`, +) + +interface LinkBoxListProps { + items: Array + variant?: LinkBoxListVariant + LinkBoxProps?: Omit, keyof LinkBoxProps> +} + +const LinkBoxList = ({ + items, + variant = "default", + LinkBoxProps, +}: LinkBoxListProps) => ( + + + {items.map((item) => ( +
  • + +
  • + ))} +
    + +
    +) + +export default LinkBoxList diff --git a/frontend/components/NewLayout/Frontpage/Hero.tsx b/frontend/components/NewLayout/Frontpage/Hero.tsx index d40eb7a13..1d917691f 100644 --- a/frontend/components/NewLayout/Frontpage/Hero.tsx +++ b/frontend/components/NewLayout/Frontpage/Hero.tsx @@ -230,7 +230,7 @@ function Hero() { prop !== "count", -})<{ count?: number }>( - ({ theme, count = 4 }) => ` - display: grid; - grid-gap: 1rem; - grid-template-columns: ${ - count % 2 === 0 - ? "repeat(auto-fit, minmax(200px, 1fr))" - : `repeat(auto-fit, minmax(166px, 1fr))` - }; - padding: 2rem; - justify-content: center; - width: 80%; - - ${theme.breakpoints.down("lg")} { - grid-template-columns: ${ - count % 2 === 0 - ? "repeat(auto-fit, minmax(300px, 1fr))" - : `repeat(auto-fit, minmax(450px, 1fr))` - }; - } - - ${theme.breakpoints.down("xs")} { - padding: 0; - width: 100%; - grid-template-columns: 1fr; - } -`, -) - -const HypeCardHeader = styled(CardHeader)` - background-color: #f5f5f5; -` -interface HypeCardProps { - item: NaviItem +type CustomNaviItem = { + title: string + text: string + linkText: string + img?: string + imgDimensions?: { width: number; height: number } + link: string + titleImg?: string + titleImgDimensions?: { width: number; height: number } } -const HypeCard = ({ item: { title, text } }: HypeCardProps) => { - return ( - - - - {title} - - - - {text} - - - ) -} function Hype() { const t = useTranslator(NaviTranslations) const items = t("naviItems") as readonly NaviItem[] + const customItems = t("customNaviItems") as readonly CustomNaviItem[] + + const listItems: Array = useMemo( + () => + items.map(({ title, text, link, linkText }) => ({ + title, + description: text, + /*imageProps: { + src: '/images/navi/' + item.img, + alt: item.title, + fill: true + },*/ + linkProps: { + href: link, + children: linkText, + }, + })), + [items], + ) + + const customListItems: Array = useMemo( + () => + customItems.map( + ({ title, text, titleImg, titleImgDimensions, link, linkText }) => ({ + title, + titleImage: titleImg, + description: text, + ...(titleImg + ? { + titleImageProps: { + src: "/images/navi/" + titleImg, + alt: title, + ...(titleImgDimensions ?? { fill: true }), + }, + } + : {}), + linkProps: { + href: link, + children: linkText, + }, + }), + ), + [customItems], + ) - // remember to test with divisible by 2 and 3 return ( - - - {items.map((item) => ( - - ))} - - + <> + + {customListItems.length > 0 && ( + <> + + + + )} + ) } diff --git a/frontend/pages/_new/index.tsx b/frontend/pages/_new/index.tsx index 73ad97ee4..e6b844792 100644 --- a/frontend/pages/_new/index.tsx +++ b/frontend/pages/_new/index.tsx @@ -5,7 +5,7 @@ import { styled } from "@mui/material/styles" import Hero from "/components/NewLayout/Frontpage/Hero" import Hype from "/components/NewLayout/Frontpage/Hype" import { ModuleNavigation } from "/components/NewLayout/Frontpage/Modules" -import News from "/components/NewLayout/Frontpage/News" +// import News from "/components/NewLayout/Frontpage/News" import SelectedCourses from "/components/NewLayout/Frontpage/SelectedCourses" const HomeContainer = styled("div")` @@ -19,7 +19,7 @@ const Home = () => { - + {/**/} diff --git a/frontend/public/images/new/doggos.png b/frontend/public/images/new/doggos.png new file mode 100644 index 000000000..8b221a8db Binary files /dev/null and b/frontend/public/images/new/doggos.png differ