From eef279e71332e366491d04cb050139a278263820 Mon Sep 17 00:00:00 2001 From: Carey Gumaer Date: Tue, 2 Jul 2024 17:55:14 -0400 Subject: [PATCH 01/16] add DefaultChannelSkeleton and use it when the channel type is not unit --- .../src/pages/ChannelPage/ChannelPage.tsx | 20 +- .../ChannelPage/DefaultChannelSkeleton.tsx | 192 ++++++++++++++++++ .../src/components/Banner/Banner.tsx | 41 +++- 3 files changed, 241 insertions(+), 12 deletions(-) create mode 100644 frontends/mit-open/src/pages/ChannelPage/DefaultChannelSkeleton.tsx diff --git a/frontends/mit-open/src/pages/ChannelPage/ChannelPage.tsx b/frontends/mit-open/src/pages/ChannelPage/ChannelPage.tsx index 602382ce62..467cf44f19 100644 --- a/frontends/mit-open/src/pages/ChannelPage/ChannelPage.tsx +++ b/frontends/mit-open/src/pages/ChannelPage/ChannelPage.tsx @@ -11,6 +11,7 @@ import type { import { ChannelTypeEnum } from "api/v0" import TestimonialDisplay from "@/page-components/TestimonialDisplay/TestimonialDisplay" import { styled } from "ol-components" +import DefaultChannelSkeleton from "./DefaultChannelSkeleton" export const StyledTestimonialDisplay = styled(TestimonialDisplay)` margin-bottom: 80px; @@ -40,12 +41,11 @@ const ChannelPage: React.FC = () => { return ( name && - channelType && ( + channelType && + (channelType === "unit" ? (

{channelQuery.data?.public_description}

- {channelType === "unit" ? ( - - ) : null} + {channelQuery.data?.search_filter && ( { /> )}
- ) + ) : ( + +

{channelQuery.data?.public_description}

+ {channelQuery.data?.search_filter && ( + + )} +
+ )) ) } diff --git a/frontends/mit-open/src/pages/ChannelPage/DefaultChannelSkeleton.tsx b/frontends/mit-open/src/pages/ChannelPage/DefaultChannelSkeleton.tsx new file mode 100644 index 0000000000..303ae05702 --- /dev/null +++ b/frontends/mit-open/src/pages/ChannelPage/DefaultChannelSkeleton.tsx @@ -0,0 +1,192 @@ +import React from "react" +import { + styled, + Container, + Typography, + Breadcrumbs, + Banner, +} from "ol-components" +import { MetaTags } from "ol-utilities" +import { SearchSubscriptionToggle } from "@/page-components/SearchSubscriptionToggle/SearchSubscriptionToggle" +import { useChannelDetail } from "api/hooks/channels" +import ChannelMenu from "@/components/ChannelMenu/ChannelMenu" +import ChannelAvatar from "@/components/ChannelAvatar/ChannelAvatar" +import { SourceTypeEnum } from "api" +import { DEPARTMENTS, HOME, TOPICS, UNITS } from "../../common/urls" + +const Page = styled.div({}) + +const HeadingTextContainer = styled.div(({ theme }) => ({ + display: "flex", + flexDirection: "row", + alignItems: "center", + flexGrow: 0, + flexShrink: 0, + order: 2, + my: 1, + [theme.breakpoints.down("sm")]: { + width: "100%", + }, + [theme.breakpoints.up("md")]: { + width: "80%", + }, +})) + +const ChannelControlsContainer = styled.div(({ theme }) => ({ + display: "flex", + flexDirection: "row", + alignItems: "end", + flexGrow: 0, + flexShrink: 0, + order: 2, + [theme.breakpoints.down("xs")]: { + width: "100%", + }, + [theme.breakpoints.down("sm")]: { + mt: "8px", + mb: "48px", + }, + [theme.breakpoints.up("md")]: { + mt: "0px", + mb: "48px", + width: "15%", + }, +})) + +export const ChannelTitleRow = styled.div` + display: flex; + flex-direction: row; + align-items: center; + + h1 a { + &:hover { + text-decoration: none; + } + } +` + +export const ChannelControls = styled.div` + position: relative; + min-height: 38px; + display: flex; +` + +interface DefaultChannelSkeletonProps { + children: React.ReactNode + channelType: string + name: string +} +const NAV_PATH: { [key: string]: { href: string; label: string } } = { + topic: { + href: TOPICS, + label: "Browse by Topic", + }, + department: { + href: DEPARTMENTS, + label: "Browse by Academic Department", + }, + unit: { + href: UNITS, + label: "MIT Units", + }, + pathway: { + href: "", + label: "Pathways", + }, +} + +/** + * Common structure for channel-oriented pages. + * + * Renders the channel title and avatar in a banner. + */ +const DefaultChannelSkeleton: React.FC = ({ + children, + channelType, + name, +}) => { + const channel = useChannelDetail(String(channelType), String(name)) + const urlParams = new URLSearchParams(channel.data?.search_filter) + const displayConfiguration = channel.data?.configuration + + return ( + + + + } + title={ + displayConfiguration?.logo && channel.data ? ( + + ) : ( + channel.data?.title + ) + } + description="" + backgroundUrl={ + displayConfiguration?.banner_background ?? + "/static/images/background_steps.jpeg" + } + action={ + + + {channel.data?.search_filter ? ( + + ) : null} + {channel.data?.is_moderator ? ( + + ) : null} + + + } + /> + + + {displayConfiguration?.heading ? ( + + + {displayConfiguration.heading} + + + ) : ( + <> + )} + {displayConfiguration?.sub_heading ? ( + + + {displayConfiguration.sub_heading} + + + ) : ( + <> + )} + + + {children} + + ) +} + +export default DefaultChannelSkeleton diff --git a/frontends/ol-components/src/components/Banner/Banner.tsx b/frontends/ol-components/src/components/Banner/Banner.tsx index 29a0556378..043285b1bf 100644 --- a/frontends/ol-components/src/components/Banner/Banner.tsx +++ b/frontends/ol-components/src/components/Banner/Banner.tsx @@ -37,10 +37,31 @@ const NavText = styled(Typography)(({ theme }) => ({ marginBottom: "4px", })) +const InnerContainer = styled.div(({ theme }) => ({ + display: "flex", + flexDirection: "row", + alignItems: "flex-start", + justifyContent: "space-between", + [theme.breakpoints.down("sm")]: { + flexDirection: "column", + }, +})) + +const TitleContainer = styled.div({ + display: "flex", + flexDirection: "column", +}) + +const ActionsContainer = styled.div({ + display: "flex", + flexDirection: "row", +}) + type BannerProps = BannerWrapperProps & { description: React.ReactNode title: React.ReactNode navText: React.ReactNode + action?: React.ReactNode } /** @@ -52,17 +73,23 @@ const Banner = ({ description, title, navText, + action, }: BannerProps) => { return ( - {navText} - - {title} - - - {description} - + + + {navText} + + {title} + + + {description} + + + {action} + ) From 2d926cfe5e44b08a78d6f0699da56e43c08548a8 Mon Sep 17 00:00:00 2001 From: Carey Gumaer Date: Mon, 8 Jul 2024 16:54:35 -0400 Subject: [PATCH 02/16] use separate templates for units and other channel types --- .../src/pages/ChannelPage/ChannelPage.tsx | 16 +- .../pages/ChannelPage/ChannelPageSkeleton.tsx | 315 +----------------- .../pages/ChannelPage/UnitChannelSkeleton.tsx | 273 +++++++++++++++ 3 files changed, 286 insertions(+), 318 deletions(-) create mode 100644 frontends/mit-open/src/pages/ChannelPage/UnitChannelSkeleton.tsx diff --git a/frontends/mit-open/src/pages/ChannelPage/ChannelPage.tsx b/frontends/mit-open/src/pages/ChannelPage/ChannelPage.tsx index 467cf44f19..f8eb2aa2ea 100644 --- a/frontends/mit-open/src/pages/ChannelPage/ChannelPage.tsx +++ b/frontends/mit-open/src/pages/ChannelPage/ChannelPage.tsx @@ -11,7 +11,6 @@ import type { import { ChannelTypeEnum } from "api/v0" import TestimonialDisplay from "@/page-components/TestimonialDisplay/TestimonialDisplay" import { styled } from "ol-components" -import DefaultChannelSkeleton from "./DefaultChannelSkeleton" export const StyledTestimonialDisplay = styled(TestimonialDisplay)` margin-bottom: 80px; @@ -41,8 +40,7 @@ const ChannelPage: React.FC = () => { return ( name && - channelType && - (channelType === "unit" ? ( + channelType && (

{channelQuery.data?.public_description}

@@ -53,17 +51,7 @@ const ChannelPage: React.FC = () => { /> )}
- ) : ( - -

{channelQuery.data?.public_description}

- {channelQuery.data?.search_filter && ( - - )} -
- )) + ) ) } diff --git a/frontends/mit-open/src/pages/ChannelPage/ChannelPageSkeleton.tsx b/frontends/mit-open/src/pages/ChannelPage/ChannelPageSkeleton.tsx index 2971c50264..2355e32793 100644 --- a/frontends/mit-open/src/pages/ChannelPage/ChannelPageSkeleton.tsx +++ b/frontends/mit-open/src/pages/ChannelPage/ChannelPageSkeleton.tsx @@ -1,75 +1,13 @@ -import React, { useMemo } from "react" -import { Link } from "react-router-dom" -import * as routes from "../../common/urls" -import { - BannerPage, - styled, - Container, - Typography, - Box, - Breadcrumbs, -} from "ol-components" -import { MetaTags } from "ol-utilities" -import { SearchSubscriptionToggle } from "@/page-components/SearchSubscriptionToggle/SearchSubscriptionToggle" -import { ChannelDetails } from "@/page-components/ChannelDetails/ChannelDetails" -import { useChannelDetail } from "api/hooks/channels" -import ChannelMenu from "@/components/ChannelMenu/ChannelMenu" -import ChannelAvatar from "@/components/ChannelAvatar/ChannelAvatar" -import ResourceCarousel, { - ResourceCarouselProps, -} from "@/page-components/ResourceCarousel/ResourceCarousel" -import { SourceTypeEnum } from "api" -import { getSearchParamMap } from "@/common/utils" -import { DEPARTMENTS, HOME, TOPICS, UNITS } from "../../common/urls" - -export const ChannelTitleRow = styled.div` - display: flex; - flex-direction: row; - align-items: center; - - h1 a { - &:hover { - text-decoration: none; - } - } -` - -const FeaturedCoursesCarousel = styled(ResourceCarousel)(({ theme }) => ({ - margin: "80px 0", - [theme.breakpoints.down("sm")]: { - marginTop: "32px", - marginBottom: "32px", - }, -})) -export const ChannelControls = styled.div` - position: relative; - min-height: 38px; - display: flex; -` +import React from "react" +import UnitChannelSkeleton from "./UnitChannelSkeleton" +import DefaultChannelSkeleton from "./DefaultChannelSkeleton" +import { ChannelTypeEnum } from "api/v0" interface ChannelSkeletonProps { children: React.ReactNode channelType: string name: string } -const NAV_PATH: { [key: string]: { href: string; label: string } } = { - topic: { - href: TOPICS, - label: "Browse by Topic", - }, - department: { - href: DEPARTMENTS, - label: "Browse by Academic Department", - }, - unit: { - href: UNITS, - label: "MIT Units", - }, - pathway: { - href: "", - label: "Pathways", - }, -} /** * Common structure for channel-oriented pages. @@ -81,246 +19,15 @@ const ChannelSkeletonProps: React.FC = ({ channelType, name, }) => { - const channel = useChannelDetail(String(channelType), String(name)) - const urlParams = new URLSearchParams(channel.data?.search_filter) - const displayConfiguration = channel.data?.configuration - - const urlParamMap: Record = useMemo(() => { - const urlParams = new URLSearchParams(channel.data?.search_filter) - return getSearchParamMap(urlParams) - }, [channel]) - - const FEATURED_RESOURCES_CAROUSEL: ResourceCarouselProps["config"] = [ - { - cardProps: { size: "medium" }, - data: { - type: "lr_featured", - params: { limit: 12, ...urlParamMap }, - }, - label: undefined, - }, - ] + const SkeletonTemplate = + channelType === ChannelTypeEnum.Unit + ? UnitChannelSkeleton + : DefaultChannelSkeleton return ( - <> - - - - - {channel.data && ( - - - ({ - flexGrow: 1, - flexShrink: 0, - order: 1, - py: "24px", - - [theme.breakpoints.down("md")]: { - py: 0, - pb: "8px", - }, - [theme.breakpoints.down("sm")]: { - width: "100%", - }, - })} - > - {displayConfiguration?.logo ? ( - - ) : ( - - - {channel.data.title} - - - )} - - {displayConfiguration.heading ? ( - - - {displayConfiguration.heading} - - - ) : ( - <> - )} - - - {displayConfiguration.sub_heading} - - - {channelType === "unit" ? ( - - - {channel.data?.search_filter ? ( - - ) : null} - {channel.data?.is_moderator ? ( - - ) : null} - - - ) : null} - - {channelType === "unit" ? ( - - - - ) : ( - - - {channel.data?.search_filter ? ( - - ) : null} - {channel.data?.is_moderator ? ( - - ) : null} - - - )} - - )} - - - } - > - {channelType === "unit" ? ( - - - - ) : null} - {children} - - + + {children} + ) } diff --git a/frontends/mit-open/src/pages/ChannelPage/UnitChannelSkeleton.tsx b/frontends/mit-open/src/pages/ChannelPage/UnitChannelSkeleton.tsx new file mode 100644 index 0000000000..258d141693 --- /dev/null +++ b/frontends/mit-open/src/pages/ChannelPage/UnitChannelSkeleton.tsx @@ -0,0 +1,273 @@ +import React, { useMemo } from "react" +import { Link } from "react-router-dom" +import * as routes from "../../common/urls" +import { + BannerPage, + styled, + Container, + Typography, + Box, + Breadcrumbs, +} from "ol-components" +import { MetaTags } from "ol-utilities" +import { SearchSubscriptionToggle } from "@/page-components/SearchSubscriptionToggle/SearchSubscriptionToggle" +import { ChannelDetails } from "@/page-components/ChannelDetails/ChannelDetails" +import { useChannelDetail } from "api/hooks/channels" +import ChannelMenu from "@/components/ChannelMenu/ChannelMenu" +import ChannelAvatar from "@/components/ChannelAvatar/ChannelAvatar" +import ResourceCarousel, { + ResourceCarouselProps, +} from "@/page-components/ResourceCarousel/ResourceCarousel" +import { SourceTypeEnum } from "api" +import { getSearchParamMap } from "@/common/utils" +import { HOME, UNITS } from "../../common/urls" +import { ChannelTypeEnum } from "api/v0" + +const UNITS_LABEL = "MIT Units" + +export const ChannelTitleRow = styled.div` + display: flex; + flex-direction: row; + align-items: center; + + h1 a { + &:hover { + text-decoration: none; + } + } +` + +const FeaturedCoursesCarousel = styled(ResourceCarousel)(({ theme }) => ({ + margin: "80px 0", + [theme.breakpoints.down("sm")]: { + marginTop: "32px", + marginBottom: "32px", + }, +})) +export const ChannelControls = styled.div` + position: relative; + min-height: 38px; + display: flex; +` + +interface UnitChannelSkeletonProps { + children: React.ReactNode + name: string +} + +/** + * Common structure for channel-oriented pages. + * + * Renders the channel title and avatar in a banner. + */ +const UnitChannelSkeleton: React.FC = ({ + children, + name, +}) => { + const channel = useChannelDetail(ChannelTypeEnum.Unit, String(name)) + const urlParams = new URLSearchParams(channel.data?.search_filter) + const displayConfiguration = channel.data?.configuration + + const urlParamMap: Record = useMemo(() => { + const urlParams = new URLSearchParams(channel.data?.search_filter) + return getSearchParamMap(urlParams) + }, [channel]) + + const FEATURED_RESOURCES_CAROUSEL: ResourceCarouselProps["config"] = [ + { + cardProps: { size: "medium" }, + data: { + type: "lr_featured", + params: { limit: 12, ...urlParamMap }, + }, + label: undefined, + }, + ] + + return ( + <> + + + + + {channel.data && ( + + + ({ + flexGrow: 1, + flexShrink: 0, + order: 1, + py: "24px", + + [theme.breakpoints.down("md")]: { + py: 0, + pb: "8px", + }, + [theme.breakpoints.down("sm")]: { + width: "100%", + }, + })} + > + {displayConfiguration?.logo ? ( + + ) : ( + + + {channel.data.title} + + + )} + + {displayConfiguration.heading ? ( + + + {displayConfiguration.heading} + + + ) : ( + <> + )} + + + {displayConfiguration.sub_heading} + + + + + {channel.data?.search_filter ? ( + + ) : null} + {channel.data?.is_moderator ? ( + + ) : null} + + + + + + + + )} + + + } + > + + + + {children} + + + ) +} + +export default UnitChannelSkeleton From 4b74c8d53a184b36dfe57be29c584bfc77706554 Mon Sep 17 00:00:00 2001 From: Carey Gumaer Date: Mon, 8 Jul 2024 17:21:17 -0400 Subject: [PATCH 03/16] remove usage of BannerPage --- .../pages/ChannelPage/UnitChannelSkeleton.tsx | 306 ++++++++---------- 1 file changed, 128 insertions(+), 178 deletions(-) diff --git a/frontends/mit-open/src/pages/ChannelPage/UnitChannelSkeleton.tsx b/frontends/mit-open/src/pages/ChannelPage/UnitChannelSkeleton.tsx index 258d141693..1c8db2cde6 100644 --- a/frontends/mit-open/src/pages/ChannelPage/UnitChannelSkeleton.tsx +++ b/frontends/mit-open/src/pages/ChannelPage/UnitChannelSkeleton.tsx @@ -1,13 +1,11 @@ import React, { useMemo } from "react" -import { Link } from "react-router-dom" -import * as routes from "../../common/urls" import { - BannerPage, styled, Container, Typography, Box, Breadcrumbs, + Banner, } from "ol-components" import { MetaTags } from "ol-utilities" import { SearchSubscriptionToggle } from "@/page-components/SearchSubscriptionToggle/SearchSubscriptionToggle" @@ -25,6 +23,8 @@ import { ChannelTypeEnum } from "api/v0" const UNITS_LABEL = "MIT Units" +const Page = styled.div({}) + export const ChannelTitleRow = styled.div` display: flex; flex-direction: row; @@ -85,188 +85,138 @@ const UnitChannelSkeleton: React.FC = ({ ] return ( - <> + - - + } + title={ + displayConfiguration?.logo && channel.data ? ( + - - {channel.data && ( - - - ({ - flexGrow: 1, - flexShrink: 0, - order: 1, - py: "24px", - - [theme.breakpoints.down("md")]: { - py: 0, - pb: "8px", - }, - [theme.breakpoints.down("sm")]: { - width: "100%", - }, - })} - > - {displayConfiguration?.logo ? ( - - ) : ( - - - {channel.data.title} - - - )} - - {displayConfiguration.heading ? ( - - - {displayConfiguration.heading} - - - ) : ( - <> - )} - - - {displayConfiguration.sub_heading} - - - - - {channel.data?.search_filter ? ( - - ) : null} - {channel.data?.is_moderator ? ( - - ) : null} - - - - - - - - )} - - + ) : ( + channel.data?.title + ) } - > - - - + description={ + <> + {displayConfiguration?.heading ? ( + + + {displayConfiguration.heading} + + + ) : ( + <> + )} + {displayConfiguration?.sub_heading ? ( + + + {displayConfiguration.sub_heading} + + + ) : ( + <> + )} + + + {channel.data?.search_filter ? ( + + ) : null} + {channel.data?.is_moderator ? ( + + ) : null} + + + + } + action={ + channel.data && ( + + + + ) + } + /> + + {children} - - + + ) } From 8c68e5394696fec906737291e110bf0b4ae8bc49 Mon Sep 17 00:00:00 2001 From: Carey Gumaer Date: Mon, 8 Jul 2024 19:00:42 -0400 Subject: [PATCH 04/16] align styles --- .../ChannelPage/DefaultChannelSkeleton.tsx | 6 +- .../pages/ChannelPage/UnitChannelSkeleton.tsx | 158 ++++++++---------- .../DepartmentListingPage.tsx | 4 +- .../TopicListingPage/TopicsListingPage.tsx | 4 +- .../UnitsListingPage/UnitsListingPage.tsx | 4 +- .../src/components/Banner/Banner.tsx | 108 ++++++++---- 6 files changed, 153 insertions(+), 131 deletions(-) diff --git a/frontends/mit-open/src/pages/ChannelPage/DefaultChannelSkeleton.tsx b/frontends/mit-open/src/pages/ChannelPage/DefaultChannelSkeleton.tsx index 303ae05702..f7489d7414 100644 --- a/frontends/mit-open/src/pages/ChannelPage/DefaultChannelSkeleton.tsx +++ b/frontends/mit-open/src/pages/ChannelPage/DefaultChannelSkeleton.tsx @@ -126,7 +126,7 @@ const DefaultChannelSkeleton: React.FC = ({ current={channel.data?.title} /> } - title={ + header={ displayConfiguration?.logo && channel.data ? ( = ({ channel.data?.title ) } - description="" + subHeader="" backgroundUrl={ displayConfiguration?.banner_background ?? "/static/images/background_steps.jpeg" } - action={ + extraRight={ {channel.data?.search_filter ? ( diff --git a/frontends/mit-open/src/pages/ChannelPage/UnitChannelSkeleton.tsx b/frontends/mit-open/src/pages/ChannelPage/UnitChannelSkeleton.tsx index 1c8db2cde6..04b1830e7d 100644 --- a/frontends/mit-open/src/pages/ChannelPage/UnitChannelSkeleton.tsx +++ b/frontends/mit-open/src/pages/ChannelPage/UnitChannelSkeleton.tsx @@ -1,12 +1,5 @@ import React, { useMemo } from "react" -import { - styled, - Container, - Typography, - Box, - Breadcrumbs, - Banner, -} from "ol-components" +import { styled, Container, Box, Breadcrumbs, Banner } from "ol-components" import { MetaTags } from "ol-utilities" import { SearchSubscriptionToggle } from "@/page-components/SearchSubscriptionToggle/SearchSubscriptionToggle" import { ChannelDetails } from "@/page-components/ChannelDetails/ChannelDetails" @@ -84,6 +77,11 @@ const UnitChannelSkeleton: React.FC = ({ }, ] + const headerStyles = { + width: { md: "80%", sm: "100%" }, + my: 1, + } + return ( @@ -92,6 +90,9 @@ const UnitChannelSkeleton: React.FC = ({ displayConfiguration?.banner_background ?? "/static/images/background_steps.jpeg" } + backgroundSize="2000px auto" + backgroundDim={30} + containerPadding={"48px 0 64px 0"} navText={ = ({ current={channel.data?.title} /> } - title={ + avatar={ displayConfiguration?.logo && channel.data ? ( - - ) : ( - channel.data?.title - ) - } - description={ - <> - {displayConfiguration?.heading ? ( - - - {displayConfiguration.heading} - - - ) : ( - <> - )} - {displayConfiguration?.sub_heading ? ( - - - {displayConfiguration.sub_heading} - - - ) : ( - <> - )} ({ + flexGrow: 1, + flexShrink: 0, + order: 1, + py: "24px", + + [theme.breakpoints.down("md")]: { + py: 0, + pb: "8px", + }, + [theme.breakpoints.down("sm")]: { + width: "100%", + }, + })} > - - {channel.data?.search_filter ? ( - - ) : null} - {channel.data?.is_moderator ? ( - - ) : null} - + - + ) : null } - action={ + header={displayConfiguration?.heading} + headerTypography={{ xs: "h4", md: "h4" }} + headerStyles={headerStyles} + subHeader={displayConfiguration?.sub_heading} + subHeaderStyles={headerStyles} + subHeaderTypography={{ xs: "body1", md: "body1" }} + extraHeader={ + + + {channel.data?.search_filter ? ( + + ) : null} + {channel.data?.is_moderator ? ( + + ) : null} + + + } + extraRight={ channel.data && ( = ({ alignSelf="center" display="flex" sx={{ - order: 2, - flexGrow: 0, - flexShrink: 0, width: { md: "408px", xs: "100%" }, }} > diff --git a/frontends/mit-open/src/pages/DepartmentListingPage/DepartmentListingPage.tsx b/frontends/mit-open/src/pages/DepartmentListingPage/DepartmentListingPage.tsx index f40a37f645..5a4bb7d2a7 100644 --- a/frontends/mit-open/src/pages/DepartmentListingPage/DepartmentListingPage.tsx +++ b/frontends/mit-open/src/pages/DepartmentListingPage/DepartmentListingPage.tsx @@ -217,8 +217,8 @@ const DepartmentListingPage: React.FC = () => { { current="Topics" /> } - title="Browse by Topic" - description="" + header="Browse by Topic" + subHeader="" backgroundUrl={TOPICS_BANNER_IMAGE} /> diff --git a/frontends/mit-open/src/pages/UnitsListingPage/UnitsListingPage.tsx b/frontends/mit-open/src/pages/UnitsListingPage/UnitsListingPage.tsx index b6b0e556ed..906dd38406 100644 --- a/frontends/mit-open/src/pages/UnitsListingPage/UnitsListingPage.tsx +++ b/frontends/mit-open/src/pages/UnitsListingPage/UnitsListingPage.tsx @@ -414,8 +414,8 @@ const UnitsListingPage: React.FC = () => { current="MIT Units" /> } - title="Academic & Professional Learning" - description="Non-degree learning resources tailored to the needs of students and working professionals." + header="Academic & Professional Learning" + subHeader="Non-degree learning resources tailored to the needs of students and working professionals." backgroundUrl={UNITS_BANNER_IMAGE} /> diff --git a/frontends/ol-components/src/components/Banner/Banner.tsx b/frontends/ol-components/src/components/Banner/Banner.tsx index 043285b1bf..e98c8ecab4 100644 --- a/frontends/ol-components/src/components/Banner/Banner.tsx +++ b/frontends/ol-components/src/components/Banner/Banner.tsx @@ -2,8 +2,10 @@ import React from "react" import styled from "@emotion/styled" import Typography from "@mui/material/Typography" import Container from "@mui/material/Container" +import { Box, Theme } from "../.." +import { ResponsiveStyleValue, SxProps } from "@mui/system" -const Description = styled(Typography)(({ theme }) => ({ +const SubHeader = styled(Typography)(({ theme }) => ({ maxWidth: "700px", marginTop: "8px", [theme.breakpoints.down("sm")]: { @@ -13,55 +15,71 @@ const Description = styled(Typography)(({ theme }) => ({ type BannerWrapperProps = { backgroundUrl: string + backgroundSize?: string + backgroundDim?: number + containerPadding: string } /** * This is a full-width banner component that takes a background image URL. */ const BannerWrapper = styled.div( - ({ theme, backgroundUrl }) => ({ - backgroundImage: `url(${backgroundUrl})`, - backgroundSize: "cover", + ({ + theme, + backgroundUrl, + backgroundSize = "cover", + backgroundDim = 0, + containerPadding = "48px 0 48px 0", + }) => ({ + backgroundAttachment: "fixed", + backgroundImage: `linear-gradient(rgba(0 0 0 / ${backgroundDim}%), rgba(0 0 0 / ${backgroundDim}%)), url('${backgroundUrl}')`, + backgroundSize: backgroundSize, color: theme.custom.colors.white, - paddingTop: "48px", - paddingBottom: "48px", + padding: containerPadding, [theme.breakpoints.down("sm")]: { - paddingTop: "32px", - paddingBottom: "32px", + padding: "32px 0 32px 0", }, }), ) -const NavText = styled(Typography)(({ theme }) => ({ - color: theme.custom.colors.lightGray2, - marginBottom: "4px", -})) - const InnerContainer = styled.div(({ theme }) => ({ display: "flex", flexDirection: "row", alignItems: "flex-start", justifyContent: "space-between", - [theme.breakpoints.down("sm")]: { + [theme.breakpoints.down("md")]: { flexDirection: "column", }, })) -const TitleContainer = styled.div({ +const HeaderContainer = styled.div({ display: "flex", flexDirection: "column", }) -const ActionsContainer = styled.div({ +const RightContainer = styled.div(({ theme }) => ({ display: "flex", flexDirection: "row", -}) + [theme.breakpoints.down("md")]: { + width: "100%", + }, +})) type BannerProps = BannerWrapperProps & { - description: React.ReactNode - title: React.ReactNode + backgroundUrl: string + backgroundSize?: string + backgroundDim?: number + containerPadding?: string navText: React.ReactNode - action?: React.ReactNode + avatar?: React.ReactNode + header: React.ReactNode + headerTypography?: ResponsiveStyleValue + headerStyles?: SxProps + subHeader?: React.ReactNode + subHeaderTypography?: ResponsiveStyleValue + subHeaderStyles?: SxProps + extraHeader?: React.ReactNode + extraRight?: React.ReactNode } /** @@ -70,25 +88,49 @@ type BannerProps = BannerWrapperProps & { */ const Banner = ({ backgroundUrl, - description, - title, + backgroundSize = "cover", + backgroundDim = 0, + containerPadding = "48px 0 48px 0", navText, - action, + avatar, + header, + headerTypography, + headerStyles, + subHeader, + subHeaderTypography, + subHeaderStyles, + extraHeader, + extraRight, }: BannerProps) => { + const defaultHeaderTypography = { xs: "h2", md: "h1" } + const defaultSubHeaderTypography = { xs: "body2", md: "body1" } return ( - + + {navText} - - {navText} - - {title} + + {avatar ? {avatar} : null} + + {header} - - {description} - - - {action} + + {subHeader} + + {extraHeader} + + {extraRight} From cdc5e6b08969d400e9f54147e2319a883f671d70 Mon Sep 17 00:00:00 2001 From: Carey Gumaer Date: Mon, 8 Jul 2024 20:20:10 -0400 Subject: [PATCH 05/16] more fine tuning of the styles --- .../mit-open/src/pages/ChannelPage/UnitChannelSkeleton.tsx | 5 +++-- frontends/ol-components/src/components/Banner/Banner.tsx | 7 ++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/frontends/mit-open/src/pages/ChannelPage/UnitChannelSkeleton.tsx b/frontends/mit-open/src/pages/ChannelPage/UnitChannelSkeleton.tsx index 04b1830e7d..d3e21ac333 100644 --- a/frontends/mit-open/src/pages/ChannelPage/UnitChannelSkeleton.tsx +++ b/frontends/mit-open/src/pages/ChannelPage/UnitChannelSkeleton.tsx @@ -123,6 +123,7 @@ const UnitChannelSkeleton: React.FC = ({ pb: "8px", }, [theme.breakpoints.down("sm")]: { + pt: "32px", width: "100%", }, })} @@ -137,11 +138,11 @@ const UnitChannelSkeleton: React.FC = ({ ) : null } header={displayConfiguration?.heading} - headerTypography={{ xs: "h4", md: "h4" }} + headerTypography={{ xs: "h5", md: "h4" }} headerStyles={headerStyles} subHeader={displayConfiguration?.sub_heading} subHeaderStyles={headerStyles} - subHeaderTypography={{ xs: "body1", md: "body1" }} + subHeaderTypography={{ xs: "body2", md: "body1" }} extraHeader={ ({ +const SubHeader = styled(Typography)({ maxWidth: "700px", marginTop: "8px", - [theme.breakpoints.down("sm")]: { - marginTop: "16px", - }, -})) +}) type BannerWrapperProps = { backgroundUrl: string From a5db8c3d056f6b4491905c88aaa6d1ccc0a7b43c Mon Sep 17 00:00:00 2001 From: Carey Gumaer Date: Mon, 8 Jul 2024 21:10:47 -0400 Subject: [PATCH 06/16] fix tests --- .../pages/ChannelPage/ChannelPage.test.tsx | 20 +++++++++---------- .../src/pages/ChannelPage/ChannelPage.tsx | 4 +++- .../pages/ChannelPage/ChannelSearch.test.tsx | 2 +- .../ChannelPage/DefaultChannelSkeleton.tsx | 11 +++++----- .../src/components/Banner/Banner.tsx | 16 +++++++++------ 5 files changed, 30 insertions(+), 23 deletions(-) diff --git a/frontends/mit-open/src/pages/ChannelPage/ChannelPage.test.tsx b/frontends/mit-open/src/pages/ChannelPage/ChannelPage.test.tsx index 55c0606839..7f807138b1 100644 --- a/frontends/mit-open/src/pages/ChannelPage/ChannelPage.test.tsx +++ b/frontends/mit-open/src/pages/ChannelPage/ChannelPage.test.tsx @@ -105,7 +105,7 @@ describe("ChannelPage", () => { renderTestApp({ url: `/c/${channel.channel_type}/${channel.name}` }) const title = await screen.findAllByText(channel.title) - const header = title[0].closest("header") + const header = title[1].closest("header") assertInstanceOf(header, HTMLElement) const images = within(header).getAllByRole("img") as HTMLImageElement[] const headerStyles = getComputedStyle(header) @@ -158,7 +158,7 @@ describe("ChannelPage", () => { "platform=ocw&platform=mitxonline&department=8&department=9", }) renderTestApp({ url: `/c/${channel.channel_type}/${channel.name}` }) - await screen.findByText(channel.title) + await screen.findAllByText(channel.title) const expectedProps = expect.objectContaining({ constantSearchParams: { platform: ["ocw", "mitxonline"], @@ -176,7 +176,7 @@ describe("ChannelPage", () => { const { channel } = setupApis() channel.search_filter = undefined renderTestApp({ url: `/c/${channel.channel_type}/${channel.name}` }) - await screen.findByText(channel.title) + await screen.findAllByText(channel.title) expect(mockedChannelSearch).toHaveBeenCalledTimes(0) }) @@ -185,17 +185,17 @@ describe("ChannelPage", () => { const { channel } = setupApis() channel.search_filter = undefined renderTestApp({ url: `/c/${channel.channel_type}/${channel.name}` }) - await screen.findByText(channel.title) + await screen.findAllByText(channel.title) await waitFor(() => { - expect( - screen.getByText(channel.configuration.sub_heading), - ).toBeInTheDocument() + screen.getAllByText(channel.configuration.sub_heading).forEach((el) => { + expect(el).toBeInTheDocument() + }) }) await waitFor(() => { - expect( - screen.getByText(channel.configuration.heading), - ).toBeInTheDocument() + screen.getAllByText(channel.configuration.heading).forEach((el) => { + expect(el).toBeInTheDocument() + }) }) }) diff --git a/frontends/mit-open/src/pages/ChannelPage/ChannelPage.tsx b/frontends/mit-open/src/pages/ChannelPage/ChannelPage.tsx index f8eb2aa2ea..602382ce62 100644 --- a/frontends/mit-open/src/pages/ChannelPage/ChannelPage.tsx +++ b/frontends/mit-open/src/pages/ChannelPage/ChannelPage.tsx @@ -43,7 +43,9 @@ const ChannelPage: React.FC = () => { channelType && (

{channelQuery.data?.public_description}

- + {channelType === "unit" ? ( + + ) : null} {channelQuery.data?.search_filter && ( { }) setMockResponse.get(urls.userMe.get(), {}) renderTestApp({ url: `/c/${channel.channel_type}/${channel.name}` }) - await screen.findByText(channel.title) + await screen.findAllByText(channel.title) const tabpanel = await screen.findByRole("tabpanel") for (const resource of resources) { await within(tabpanel).findByText(resource.title) diff --git a/frontends/mit-open/src/pages/ChannelPage/DefaultChannelSkeleton.tsx b/frontends/mit-open/src/pages/ChannelPage/DefaultChannelSkeleton.tsx index f7489d7414..14a61a23f4 100644 --- a/frontends/mit-open/src/pages/ChannelPage/DefaultChannelSkeleton.tsx +++ b/frontends/mit-open/src/pages/ChannelPage/DefaultChannelSkeleton.tsx @@ -126,19 +126,20 @@ const DefaultChannelSkeleton: React.FC = ({ current={channel.data?.title} /> } - header={ - displayConfiguration?.logo && channel.data ? ( + avatar={ + displayConfiguration?.logo && + channel.data && ( - ) : ( - channel.data?.title ) } - subHeader="" + header={channel.data?.title} + subHeader={displayConfiguration?.heading} + extraHeader={displayConfiguration?.sub_heading} backgroundUrl={ displayConfiguration?.banner_background ?? "/static/images/background_steps.jpeg" diff --git a/frontends/ol-components/src/components/Banner/Banner.tsx b/frontends/ol-components/src/components/Banner/Banner.tsx index 257e9dfd73..416c5a6baf 100644 --- a/frontends/ol-components/src/components/Banner/Banner.tsx +++ b/frontends/ol-components/src/components/Banner/Banner.tsx @@ -2,8 +2,8 @@ import React from "react" import styled from "@emotion/styled" import Typography from "@mui/material/Typography" import Container from "@mui/material/Container" -import { Box, Theme } from "../.." import { ResponsiveStyleValue, SxProps } from "@mui/system" +import { Theme } from "../ThemeProvider/ThemeProvider" const SubHeader = styled(Typography)({ maxWidth: "700px", @@ -14,13 +14,13 @@ type BannerWrapperProps = { backgroundUrl: string backgroundSize?: string backgroundDim?: number - containerPadding: string + containerPadding?: string } /** * This is a full-width banner component that takes a background image URL. */ -const BannerWrapper = styled.div( +const BannerWrapper = styled.header( ({ theme, backgroundUrl, @@ -29,7 +29,9 @@ const BannerWrapper = styled.div( containerPadding = "48px 0 48px 0", }) => ({ backgroundAttachment: "fixed", - backgroundImage: `linear-gradient(rgba(0 0 0 / ${backgroundDim}%), rgba(0 0 0 / ${backgroundDim}%)), url('${backgroundUrl}')`, + backgroundImage: backgroundDim + ? `linear-gradient(rgba(0 0 0 / ${backgroundDim}%), rgba(0 0 0 / ${backgroundDim}%)), url('${backgroundUrl}')` + : `url(${backgroundUrl})`, backgroundSize: backgroundSize, color: theme.custom.colors.white, padding: containerPadding, @@ -112,20 +114,22 @@ const Banner = ({ {navText} - {avatar ? {avatar} : null} + {avatar ?
{avatar}
: null} {header} {subHeader} - {extraHeader} +
{extraHeader}
{extraRight}
From d41ae7d605aa8737e3d99dcdd3e57497ff999880 Mon Sep 17 00:00:00 2001 From: Carey Gumaer Date: Tue, 9 Jul 2024 11:16:15 -0400 Subject: [PATCH 07/16] remove unnecessary page wrappers --- .../src/pages/ChannelPage/DefaultChannelSkeleton.tsx | 6 ++---- .../mit-open/src/pages/ChannelPage/UnitChannelSkeleton.tsx | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/frontends/mit-open/src/pages/ChannelPage/DefaultChannelSkeleton.tsx b/frontends/mit-open/src/pages/ChannelPage/DefaultChannelSkeleton.tsx index 14a61a23f4..4e486ebb0d 100644 --- a/frontends/mit-open/src/pages/ChannelPage/DefaultChannelSkeleton.tsx +++ b/frontends/mit-open/src/pages/ChannelPage/DefaultChannelSkeleton.tsx @@ -14,8 +14,6 @@ import ChannelAvatar from "@/components/ChannelAvatar/ChannelAvatar" import { SourceTypeEnum } from "api" import { DEPARTMENTS, HOME, TOPICS, UNITS } from "../../common/urls" -const Page = styled.div({}) - const HeadingTextContainer = styled.div(({ theme }) => ({ display: "flex", flexDirection: "row", @@ -110,7 +108,7 @@ const DefaultChannelSkeleton: React.FC = ({ const displayConfiguration = channel.data?.configuration return ( - + <> = ({
{children} -
+ ) } diff --git a/frontends/mit-open/src/pages/ChannelPage/UnitChannelSkeleton.tsx b/frontends/mit-open/src/pages/ChannelPage/UnitChannelSkeleton.tsx index d3e21ac333..612c34c44c 100644 --- a/frontends/mit-open/src/pages/ChannelPage/UnitChannelSkeleton.tsx +++ b/frontends/mit-open/src/pages/ChannelPage/UnitChannelSkeleton.tsx @@ -16,8 +16,6 @@ import { ChannelTypeEnum } from "api/v0" const UNITS_LABEL = "MIT Units" -const Page = styled.div({}) - export const ChannelTitleRow = styled.div` display: flex; flex-direction: row; @@ -83,7 +81,7 @@ const UnitChannelSkeleton: React.FC = ({ } return ( - + <> = ({ /> {children} - + ) } From c4e382c7bb7a525e8d83afb3c05a533449707125 Mon Sep 17 00:00:00 2001 From: Carey Gumaer Date: Tue, 9 Jul 2024 12:45:22 -0400 Subject: [PATCH 08/16] consolidate breadcrumb target info --- .../src/pages/ChannelPage/ChannelPage.tsx | 48 +++++++++++++++++-- .../ChannelPage/DefaultChannelSkeleton.tsx | 34 +++++-------- .../pages/ChannelPage/UnitChannelSkeleton.tsx | 9 ++-- frontends/mit-open/src/routes.tsx | 2 +- 4 files changed, 59 insertions(+), 34 deletions(-) diff --git a/frontends/mit-open/src/pages/ChannelPage/ChannelPage.tsx b/frontends/mit-open/src/pages/ChannelPage/ChannelPage.tsx index 602382ce62..c830d79250 100644 --- a/frontends/mit-open/src/pages/ChannelPage/ChannelPage.tsx +++ b/frontends/mit-open/src/pages/ChannelPage/ChannelPage.tsx @@ -3,14 +3,45 @@ import { useParams } from "react-router" import ChannelPageSkeleton from "./ChannelPageSkeleton" import { useChannelDetail } from "api/hooks/channels" import FieldSearch from "./ChannelSearch" -import type { - Facets, - FacetKey, - BooleanFacets, +import { + type Facets, + type FacetKey, + type BooleanFacets, } from "@mitodl/course-search-utils" import { ChannelTypeEnum } from "api/v0" import TestimonialDisplay from "@/page-components/TestimonialDisplay/TestimonialDisplay" import { styled } from "ol-components" +import { + DEPARTMENTS as DEPARTMENTS_URL, + TOPICS as TOPICS_URL, + UNITS as UNITS_URL, +} from "@/common/urls" + +const TOPICS_LABEL = "Browse by Topic" +const DEPARTMENTS_LABEL = "Browse by Academic Department" +const UNITS_LABEL = "MIT Units" +const PATHWAYS_LABEL = "Pathways" + +const CHANNEL_TYPE_BREADCRUMB_TARGETS: { + [key: string]: { href: string; label: string } +} = { + topic: { + href: TOPICS_URL, + label: TOPICS_LABEL, + }, + department: { + href: DEPARTMENTS_URL, + label: DEPARTMENTS_LABEL, + }, + unit: { + href: UNITS_URL, + label: UNITS_LABEL, + }, + pathway: { + href: "", + label: PATHWAYS_LABEL, + }, +} export const StyledTestimonialDisplay = styled(TestimonialDisplay)` margin-bottom: 80px; @@ -57,4 +88,11 @@ const ChannelPage: React.FC = () => { ) } -export default ChannelPage +export { + ChannelPage, + TOPICS_LABEL, + DEPARTMENTS_LABEL, + UNITS_LABEL, + PATHWAYS_LABEL, + CHANNEL_TYPE_BREADCRUMB_TARGETS, +} diff --git a/frontends/mit-open/src/pages/ChannelPage/DefaultChannelSkeleton.tsx b/frontends/mit-open/src/pages/ChannelPage/DefaultChannelSkeleton.tsx index 4e486ebb0d..d9bc5e0122 100644 --- a/frontends/mit-open/src/pages/ChannelPage/DefaultChannelSkeleton.tsx +++ b/frontends/mit-open/src/pages/ChannelPage/DefaultChannelSkeleton.tsx @@ -12,7 +12,8 @@ import { useChannelDetail } from "api/hooks/channels" import ChannelMenu from "@/components/ChannelMenu/ChannelMenu" import ChannelAvatar from "@/components/ChannelAvatar/ChannelAvatar" import { SourceTypeEnum } from "api" -import { DEPARTMENTS, HOME, TOPICS, UNITS } from "../../common/urls" +import { HOME as HOME_URL } from "../../common/urls" +import { CHANNEL_TYPE_BREADCRUMB_TARGETS } from "./ChannelPage" const HeadingTextContainer = styled.div(({ theme }) => ({ display: "flex", @@ -74,24 +75,6 @@ interface DefaultChannelSkeletonProps { channelType: string name: string } -const NAV_PATH: { [key: string]: { href: string; label: string } } = { - topic: { - href: TOPICS, - label: "Browse by Topic", - }, - department: { - href: DEPARTMENTS, - label: "Browse by Academic Department", - }, - unit: { - href: UNITS, - label: "MIT Units", - }, - pathway: { - href: "", - label: "Pathways", - }, -} /** * Common structure for channel-oriented pages. @@ -109,16 +92,21 @@ const DefaultChannelSkeleton: React.FC = ({ return ( <> - + = ({ Date: Tue, 9 Jul 2024 12:58:17 -0400 Subject: [PATCH 09/16] de-flake test --- .../mit-open/src/pages/ChannelPage/ChannelPage.test.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/frontends/mit-open/src/pages/ChannelPage/ChannelPage.test.tsx b/frontends/mit-open/src/pages/ChannelPage/ChannelPage.test.tsx index 7f807138b1..54df8d0fd6 100644 --- a/frontends/mit-open/src/pages/ChannelPage/ChannelPage.test.tsx +++ b/frontends/mit-open/src/pages/ChannelPage/ChannelPage.test.tsx @@ -104,8 +104,10 @@ describe("ChannelPage", () => { const { channel } = setupApis() renderTestApp({ url: `/c/${channel.channel_type}/${channel.name}` }) - const title = await screen.findAllByText(channel.title) - const header = title[1].closest("header") + const titles = await screen.findAllByText(channel.title) + const title = titles[titles.findIndex((title) => title.nodeName === "H1")] + expect(title).toBeInTheDocument() + const header = title.closest("header") assertInstanceOf(header, HTMLElement) const images = within(header).getAllByRole("img") as HTMLImageElement[] const headerStyles = getComputedStyle(header) From 838c5f05498103c2bbc8a012b2ce121c339aeb3d Mon Sep 17 00:00:00 2001 From: Carey Gumaer Date: Tue, 9 Jul 2024 13:08:59 -0400 Subject: [PATCH 10/16] move consolidated elements to ChannelPageSkeleton --- .../src/pages/ChannelPage/ChannelPage.tsx | 40 +----------------- .../pages/ChannelPage/ChannelPageSkeleton.tsx | 42 ++++++++++++++++++- .../ChannelPage/DefaultChannelSkeleton.tsx | 2 +- .../pages/ChannelPage/UnitChannelSkeleton.tsx | 2 +- frontends/mit-open/src/routes.tsx | 2 +- 5 files changed, 44 insertions(+), 44 deletions(-) diff --git a/frontends/mit-open/src/pages/ChannelPage/ChannelPage.tsx b/frontends/mit-open/src/pages/ChannelPage/ChannelPage.tsx index c830d79250..23de9704ae 100644 --- a/frontends/mit-open/src/pages/ChannelPage/ChannelPage.tsx +++ b/frontends/mit-open/src/pages/ChannelPage/ChannelPage.tsx @@ -11,37 +11,6 @@ import { import { ChannelTypeEnum } from "api/v0" import TestimonialDisplay from "@/page-components/TestimonialDisplay/TestimonialDisplay" import { styled } from "ol-components" -import { - DEPARTMENTS as DEPARTMENTS_URL, - TOPICS as TOPICS_URL, - UNITS as UNITS_URL, -} from "@/common/urls" - -const TOPICS_LABEL = "Browse by Topic" -const DEPARTMENTS_LABEL = "Browse by Academic Department" -const UNITS_LABEL = "MIT Units" -const PATHWAYS_LABEL = "Pathways" - -const CHANNEL_TYPE_BREADCRUMB_TARGETS: { - [key: string]: { href: string; label: string } -} = { - topic: { - href: TOPICS_URL, - label: TOPICS_LABEL, - }, - department: { - href: DEPARTMENTS_URL, - label: DEPARTMENTS_LABEL, - }, - unit: { - href: UNITS_URL, - label: UNITS_LABEL, - }, - pathway: { - href: "", - label: PATHWAYS_LABEL, - }, -} export const StyledTestimonialDisplay = styled(TestimonialDisplay)` margin-bottom: 80px; @@ -88,11 +57,4 @@ const ChannelPage: React.FC = () => { ) } -export { - ChannelPage, - TOPICS_LABEL, - DEPARTMENTS_LABEL, - UNITS_LABEL, - PATHWAYS_LABEL, - CHANNEL_TYPE_BREADCRUMB_TARGETS, -} +export default ChannelPage diff --git a/frontends/mit-open/src/pages/ChannelPage/ChannelPageSkeleton.tsx b/frontends/mit-open/src/pages/ChannelPage/ChannelPageSkeleton.tsx index 2355e32793..7b35ec0f07 100644 --- a/frontends/mit-open/src/pages/ChannelPage/ChannelPageSkeleton.tsx +++ b/frontends/mit-open/src/pages/ChannelPage/ChannelPageSkeleton.tsx @@ -2,6 +2,37 @@ import React from "react" import UnitChannelSkeleton from "./UnitChannelSkeleton" import DefaultChannelSkeleton from "./DefaultChannelSkeleton" import { ChannelTypeEnum } from "api/v0" +import { + DEPARTMENTS as DEPARTMENTS_URL, + TOPICS as TOPICS_URL, + UNITS as UNITS_URL, +} from "@/common/urls" + +const TOPICS_LABEL = "Browse by Topic" +const DEPARTMENTS_LABEL = "Browse by Academic Department" +const UNITS_LABEL = "MIT Units" +const PATHWAYS_LABEL = "Pathways" + +const CHANNEL_TYPE_BREADCRUMB_TARGETS: { + [key: string]: { href: string; label: string } +} = { + topic: { + href: TOPICS_URL, + label: TOPICS_LABEL, + }, + department: { + href: DEPARTMENTS_URL, + label: DEPARTMENTS_LABEL, + }, + unit: { + href: UNITS_URL, + label: UNITS_LABEL, + }, + pathway: { + href: "", + label: PATHWAYS_LABEL, + }, +} interface ChannelSkeletonProps { children: React.ReactNode @@ -14,7 +45,7 @@ interface ChannelSkeletonProps { * * Renders the channel title and avatar in a banner. */ -const ChannelSkeletonProps: React.FC = ({ +const ChannelSkeleton: React.FC = ({ children, channelType, name, @@ -31,4 +62,11 @@ const ChannelSkeletonProps: React.FC = ({ ) } -export default ChannelSkeletonProps +export { + ChannelSkeleton, + CHANNEL_TYPE_BREADCRUMB_TARGETS, + UNITS_LABEL, + TOPICS_LABEL, + DEPARTMENTS_LABEL, + PATHWAYS_LABEL, +} diff --git a/frontends/mit-open/src/pages/ChannelPage/DefaultChannelSkeleton.tsx b/frontends/mit-open/src/pages/ChannelPage/DefaultChannelSkeleton.tsx index d9bc5e0122..b46c303386 100644 --- a/frontends/mit-open/src/pages/ChannelPage/DefaultChannelSkeleton.tsx +++ b/frontends/mit-open/src/pages/ChannelPage/DefaultChannelSkeleton.tsx @@ -13,7 +13,7 @@ import ChannelMenu from "@/components/ChannelMenu/ChannelMenu" import ChannelAvatar from "@/components/ChannelAvatar/ChannelAvatar" import { SourceTypeEnum } from "api" import { HOME as HOME_URL } from "../../common/urls" -import { CHANNEL_TYPE_BREADCRUMB_TARGETS } from "./ChannelPage" +import { CHANNEL_TYPE_BREADCRUMB_TARGETS } from "./ChannelPageSkeleton" const HeadingTextContainer = styled.div(({ theme }) => ({ display: "flex", diff --git a/frontends/mit-open/src/pages/ChannelPage/UnitChannelSkeleton.tsx b/frontends/mit-open/src/pages/ChannelPage/UnitChannelSkeleton.tsx index d2fdafebb7..f53ffd350a 100644 --- a/frontends/mit-open/src/pages/ChannelPage/UnitChannelSkeleton.tsx +++ b/frontends/mit-open/src/pages/ChannelPage/UnitChannelSkeleton.tsx @@ -13,7 +13,7 @@ import { SourceTypeEnum } from "api" import { getSearchParamMap } from "@/common/utils" import { HOME as HOME_URL, UNITS as UNITS_URL } from "../../common/urls" import { ChannelTypeEnum } from "api/v0" -import { UNITS_LABEL } from "./ChannelPage" +import { UNITS_LABEL } from "./ChannelPageSkeleton" export const ChannelTitleRow = styled.div` display: flex; diff --git a/frontends/mit-open/src/routes.tsx b/frontends/mit-open/src/routes.tsx index 2cd2794965..626daad097 100644 --- a/frontends/mit-open/src/routes.tsx +++ b/frontends/mit-open/src/routes.tsx @@ -4,7 +4,7 @@ import { ScrollRestoration } from "react-router-dom" import HomePage from "@/pages/HomePage/HomePage" import RestrictedRoute from "@/components/RestrictedRoute/RestrictedRoute" import LearningPathListingPage from "@/pages/LearningPathListingPage/LearningPathListingPage" -import { ChannelPage } from "@/pages/ChannelPage/ChannelPage" +import ChannelPage from "@/pages/ChannelPage/ChannelPage" import EditChannelPage from "@/pages/ChannelPage/EditChannelPage" import { UserListListingPage } from "./pages/UserListListingPage/UserListListingPage" From 6f1e01ee4dac91eeb45205f7647e7a9923c9c7c8 Mon Sep 17 00:00:00 2001 From: Carey Gumaer Date: Tue, 9 Jul 2024 13:20:23 -0400 Subject: [PATCH 11/16] consolidate more elements --- .../src/pages/ChannelPage/ChannelPage.tsx | 2 +- .../pages/ChannelPage/ChannelPageSkeleton.tsx | 27 +++++++++++++++++-- .../ChannelPage/DefaultChannelSkeleton.tsx | 24 ++++------------- .../src/pages/ChannelPage/EditChannelPage.tsx | 2 +- .../pages/ChannelPage/UnitChannelSkeleton.tsx | 19 +------------ 5 files changed, 33 insertions(+), 41 deletions(-) diff --git a/frontends/mit-open/src/pages/ChannelPage/ChannelPage.tsx b/frontends/mit-open/src/pages/ChannelPage/ChannelPage.tsx index 23de9704ae..029adafdfd 100644 --- a/frontends/mit-open/src/pages/ChannelPage/ChannelPage.tsx +++ b/frontends/mit-open/src/pages/ChannelPage/ChannelPage.tsx @@ -1,6 +1,6 @@ import React from "react" import { useParams } from "react-router" -import ChannelPageSkeleton from "./ChannelPageSkeleton" +import { ChannelPageSkeleton } from "./ChannelPageSkeleton" import { useChannelDetail } from "api/hooks/channels" import FieldSearch from "./ChannelSearch" import { diff --git a/frontends/mit-open/src/pages/ChannelPage/ChannelPageSkeleton.tsx b/frontends/mit-open/src/pages/ChannelPage/ChannelPageSkeleton.tsx index 7b35ec0f07..0b63ff6e95 100644 --- a/frontends/mit-open/src/pages/ChannelPage/ChannelPageSkeleton.tsx +++ b/frontends/mit-open/src/pages/ChannelPage/ChannelPageSkeleton.tsx @@ -7,6 +7,7 @@ import { TOPICS as TOPICS_URL, UNITS as UNITS_URL, } from "@/common/urls" +import { styled } from "ol-components" const TOPICS_LABEL = "Browse by Topic" const DEPARTMENTS_LABEL = "Browse by Academic Department" @@ -34,6 +35,26 @@ const CHANNEL_TYPE_BREADCRUMB_TARGETS: { }, } +const ChannelTitleRow = styled.div({ + display: "flex", + flexDirection: "row", + alignItems: "center", + + h1: { + a: { + "&:hover": { + textDecoration: "none", + }, + }, + }, +}) + +const ChannelControls = styled.div({ + position: "relative", + minHeight: "38px", + display: "flex", +}) + interface ChannelSkeletonProps { children: React.ReactNode channelType: string @@ -45,7 +66,7 @@ interface ChannelSkeletonProps { * * Renders the channel title and avatar in a banner. */ -const ChannelSkeleton: React.FC = ({ +const ChannelPageSkeleton: React.FC = ({ children, channelType, name, @@ -63,7 +84,9 @@ const ChannelSkeleton: React.FC = ({ } export { - ChannelSkeleton, + ChannelPageSkeleton, + ChannelTitleRow, + ChannelControls, CHANNEL_TYPE_BREADCRUMB_TARGETS, UNITS_LABEL, TOPICS_LABEL, diff --git a/frontends/mit-open/src/pages/ChannelPage/DefaultChannelSkeleton.tsx b/frontends/mit-open/src/pages/ChannelPage/DefaultChannelSkeleton.tsx index b46c303386..1e38ef16bc 100644 --- a/frontends/mit-open/src/pages/ChannelPage/DefaultChannelSkeleton.tsx +++ b/frontends/mit-open/src/pages/ChannelPage/DefaultChannelSkeleton.tsx @@ -13,7 +13,11 @@ import ChannelMenu from "@/components/ChannelMenu/ChannelMenu" import ChannelAvatar from "@/components/ChannelAvatar/ChannelAvatar" import { SourceTypeEnum } from "api" import { HOME as HOME_URL } from "../../common/urls" -import { CHANNEL_TYPE_BREADCRUMB_TARGETS } from "./ChannelPageSkeleton" +import { + CHANNEL_TYPE_BREADCRUMB_TARGETS, + ChannelControls, + ChannelTitleRow, +} from "./ChannelPageSkeleton" const HeadingTextContainer = styled.div(({ theme }) => ({ display: "flex", @@ -52,24 +56,6 @@ const ChannelControlsContainer = styled.div(({ theme }) => ({ }, })) -export const ChannelTitleRow = styled.div` - display: flex; - flex-direction: row; - align-items: center; - - h1 a { - &:hover { - text-decoration: none; - } - } -` - -export const ChannelControls = styled.div` - position: relative; - min-height: 38px; - display: flex; -` - interface DefaultChannelSkeletonProps { children: React.ReactNode channelType: string diff --git a/frontends/mit-open/src/pages/ChannelPage/EditChannelPage.tsx b/frontends/mit-open/src/pages/ChannelPage/EditChannelPage.tsx index d5581ee8bc..e7a55ed852 100644 --- a/frontends/mit-open/src/pages/ChannelPage/EditChannelPage.tsx +++ b/frontends/mit-open/src/pages/ChannelPage/EditChannelPage.tsx @@ -8,7 +8,7 @@ import { MetaTags } from "ol-utilities" import { GridColumn, GridContainer } from "@/components/GridLayout/GridLayout" import { useChannelDetail } from "api/hooks/channels" import EditChannelAppearanceForm from "./EditChannelAppearanceForm" -import ChannelPageSkeleton from "./ChannelPageSkeleton" +import { ChannelPageSkeleton } from "./ChannelPageSkeleton" type RouteParams = { channelType: string name: string diff --git a/frontends/mit-open/src/pages/ChannelPage/UnitChannelSkeleton.tsx b/frontends/mit-open/src/pages/ChannelPage/UnitChannelSkeleton.tsx index f53ffd350a..5a275d83f4 100644 --- a/frontends/mit-open/src/pages/ChannelPage/UnitChannelSkeleton.tsx +++ b/frontends/mit-open/src/pages/ChannelPage/UnitChannelSkeleton.tsx @@ -13,19 +13,7 @@ import { SourceTypeEnum } from "api" import { getSearchParamMap } from "@/common/utils" import { HOME as HOME_URL, UNITS as UNITS_URL } from "../../common/urls" import { ChannelTypeEnum } from "api/v0" -import { UNITS_LABEL } from "./ChannelPageSkeleton" - -export const ChannelTitleRow = styled.div` - display: flex; - flex-direction: row; - align-items: center; - - h1 a { - &:hover { - text-decoration: none; - } - } -` +import { ChannelControls, UNITS_LABEL } from "./ChannelPageSkeleton" const FeaturedCoursesCarousel = styled(ResourceCarousel)(({ theme }) => ({ margin: "80px 0", @@ -34,11 +22,6 @@ const FeaturedCoursesCarousel = styled(ResourceCarousel)(({ theme }) => ({ marginBottom: "32px", }, })) -export const ChannelControls = styled.div` - position: relative; - min-height: 38px; - display: flex; -` interface UnitChannelSkeletonProps { children: React.ReactNode From d3a0c66b40a92aabfd357a5bbccfcb5be66f6626 Mon Sep 17 00:00:00 2001 From: Carey Gumaer Date: Tue, 9 Jul 2024 14:52:15 -0400 Subject: [PATCH 12/16] flaky test fix #2 --- .../pages/ChannelPage/ChannelPage.test.tsx | 38 +++++++++++++++---- .../src/components/Banner/Banner.tsx | 1 + 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/frontends/mit-open/src/pages/ChannelPage/ChannelPage.test.tsx b/frontends/mit-open/src/pages/ChannelPage/ChannelPage.test.tsx index 54df8d0fd6..842d586e2d 100644 --- a/frontends/mit-open/src/pages/ChannelPage/ChannelPage.test.tsx +++ b/frontends/mit-open/src/pages/ChannelPage/ChannelPage.test.tsx @@ -101,19 +101,43 @@ const setupApis = ( describe("ChannelPage", () => { it("Displays the channel title, banner, and avatar", async () => { - const { channel } = setupApis() + const { channel } = setupApis({ + search_filter: "offered_by=ocw", + channel_type: "unit", + }) renderTestApp({ url: `/c/${channel.channel_type}/${channel.name}` }) - - const titles = await screen.findAllByText(channel.title) - const title = titles[titles.findIndex((title) => title.nodeName === "H1")] + const findTitle = (titles: HTMLElement[]) => { + return titles[ + titles.findIndex( + (title: HTMLElement) => + title.textContent === channel.title || + title.textContent === channel.configuration.heading, + ) + ] + } + await waitFor(() => { + const titles = screen.getAllByRole("heading") + const title = findTitle(titles) + expect(title).toBeInTheDocument() + }) + const titles = screen.getAllByRole("heading") + const title = findTitle(titles) expect(title).toBeInTheDocument() const header = title.closest("header") assertInstanceOf(header, HTMLElement) const images = within(header).getAllByRole("img") as HTMLImageElement[] const headerStyles = getComputedStyle(header) - expect(headerStyles.backgroundImage).toContain( - channel.configuration.banner_background, - ) + if (channel.channel_type !== "unit") { + /* + * unit channels are filtered out from this assertion + * because they wrap the background image in a linear-gradient, + * which causes react testing library to not render the background-image + * property at all + */ + expect(headerStyles.backgroundImage).toContain( + channel.configuration.banner_background, + ) + } expect(images[0].src).toContain(channel.configuration.logo) }) it("Displays a featured carousel if the channel type is 'unit'", async () => { diff --git a/frontends/ol-components/src/components/Banner/Banner.tsx b/frontends/ol-components/src/components/Banner/Banner.tsx index 416c5a6baf..6870c0e8bf 100644 --- a/frontends/ol-components/src/components/Banner/Banner.tsx +++ b/frontends/ol-components/src/components/Banner/Banner.tsx @@ -33,6 +33,7 @@ const BannerWrapper = styled.header( ? `linear-gradient(rgba(0 0 0 / ${backgroundDim}%), rgba(0 0 0 / ${backgroundDim}%)), url('${backgroundUrl}')` : `url(${backgroundUrl})`, backgroundSize: backgroundSize, + backgroundRepeat: "no-repeat", color: theme.custom.colors.white, padding: containerPadding, [theme.breakpoints.down("sm")]: { From 94e7d6d588b5eb09e744d1616ddc90dc1e0a9623 Mon Sep 17 00:00:00 2001 From: Carey Gumaer Date: Tue, 9 Jul 2024 14:57:02 -0400 Subject: [PATCH 13/16] rename Skeleton -> Template --- .../mit-open/src/pages/ChannelPage/ChannelPage.tsx | 6 +++--- ...nelPageSkeleton.tsx => ChannelPageTemplate.tsx} | 14 +++++++------- ...nnelSkeleton.tsx => DefaultChannelTemplate.tsx} | 8 ++++---- .../src/pages/ChannelPage/EditChannelPage.tsx | 6 +++--- ...ChannelSkeleton.tsx => UnitChannelTemplate.tsx} | 8 ++++---- 5 files changed, 21 insertions(+), 21 deletions(-) rename frontends/mit-open/src/pages/ChannelPage/{ChannelPageSkeleton.tsx => ChannelPageTemplate.tsx} (83%) rename frontends/mit-open/src/pages/ChannelPage/{DefaultChannelSkeleton.tsx => DefaultChannelTemplate.tsx} (96%) rename frontends/mit-open/src/pages/ChannelPage/{UnitChannelSkeleton.tsx => UnitChannelTemplate.tsx} (96%) diff --git a/frontends/mit-open/src/pages/ChannelPage/ChannelPage.tsx b/frontends/mit-open/src/pages/ChannelPage/ChannelPage.tsx index 029adafdfd..953f6f4329 100644 --- a/frontends/mit-open/src/pages/ChannelPage/ChannelPage.tsx +++ b/frontends/mit-open/src/pages/ChannelPage/ChannelPage.tsx @@ -1,6 +1,6 @@ import React from "react" import { useParams } from "react-router" -import { ChannelPageSkeleton } from "./ChannelPageSkeleton" +import { ChannelPageTemplate } from "./ChannelPageTemplate" import { useChannelDetail } from "api/hooks/channels" import FieldSearch from "./ChannelSearch" import { @@ -41,7 +41,7 @@ const ChannelPage: React.FC = () => { return ( name && channelType && ( - +

{channelQuery.data?.public_description}

{channelType === "unit" ? ( @@ -52,7 +52,7 @@ const ChannelPage: React.FC = () => { channelType={channelType} /> )} -
+ ) ) } diff --git a/frontends/mit-open/src/pages/ChannelPage/ChannelPageSkeleton.tsx b/frontends/mit-open/src/pages/ChannelPage/ChannelPageTemplate.tsx similarity index 83% rename from frontends/mit-open/src/pages/ChannelPage/ChannelPageSkeleton.tsx rename to frontends/mit-open/src/pages/ChannelPage/ChannelPageTemplate.tsx index 0b63ff6e95..5d9a10eedb 100644 --- a/frontends/mit-open/src/pages/ChannelPage/ChannelPageSkeleton.tsx +++ b/frontends/mit-open/src/pages/ChannelPage/ChannelPageTemplate.tsx @@ -1,6 +1,6 @@ import React from "react" -import UnitChannelSkeleton from "./UnitChannelSkeleton" -import DefaultChannelSkeleton from "./DefaultChannelSkeleton" +import UnitChannelSkeleton from "./UnitChannelTemplate" +import DefaultChannelSkeleton from "./DefaultChannelTemplate" import { ChannelTypeEnum } from "api/v0" import { DEPARTMENTS as DEPARTMENTS_URL, @@ -66,25 +66,25 @@ interface ChannelSkeletonProps { * * Renders the channel title and avatar in a banner. */ -const ChannelPageSkeleton: React.FC = ({ +const ChannelPageTemplate: React.FC = ({ children, channelType, name, }) => { - const SkeletonTemplate = + const ChannelTemplate = channelType === ChannelTypeEnum.Unit ? UnitChannelSkeleton : DefaultChannelSkeleton return ( - + {children} - + ) } export { - ChannelPageSkeleton, + ChannelPageTemplate, ChannelTitleRow, ChannelControls, CHANNEL_TYPE_BREADCRUMB_TARGETS, diff --git a/frontends/mit-open/src/pages/ChannelPage/DefaultChannelSkeleton.tsx b/frontends/mit-open/src/pages/ChannelPage/DefaultChannelTemplate.tsx similarity index 96% rename from frontends/mit-open/src/pages/ChannelPage/DefaultChannelSkeleton.tsx rename to frontends/mit-open/src/pages/ChannelPage/DefaultChannelTemplate.tsx index 1e38ef16bc..65f3401ec3 100644 --- a/frontends/mit-open/src/pages/ChannelPage/DefaultChannelSkeleton.tsx +++ b/frontends/mit-open/src/pages/ChannelPage/DefaultChannelTemplate.tsx @@ -17,7 +17,7 @@ import { CHANNEL_TYPE_BREADCRUMB_TARGETS, ChannelControls, ChannelTitleRow, -} from "./ChannelPageSkeleton" +} from "./ChannelPageTemplate" const HeadingTextContainer = styled.div(({ theme }) => ({ display: "flex", @@ -56,7 +56,7 @@ const ChannelControlsContainer = styled.div(({ theme }) => ({ }, })) -interface DefaultChannelSkeletonProps { +interface DefaultChannelTemplateProps { children: React.ReactNode channelType: string name: string @@ -67,7 +67,7 @@ interface DefaultChannelSkeletonProps { * * Renders the channel title and avatar in a banner. */ -const DefaultChannelSkeleton: React.FC = ({ +const DefaultChannelTemplate: React.FC = ({ children, channelType, name, @@ -162,4 +162,4 @@ const DefaultChannelSkeleton: React.FC = ({ ) } -export default DefaultChannelSkeleton +export default DefaultChannelTemplate diff --git a/frontends/mit-open/src/pages/ChannelPage/EditChannelPage.tsx b/frontends/mit-open/src/pages/ChannelPage/EditChannelPage.tsx index e7a55ed852..82eae36dfd 100644 --- a/frontends/mit-open/src/pages/ChannelPage/EditChannelPage.tsx +++ b/frontends/mit-open/src/pages/ChannelPage/EditChannelPage.tsx @@ -8,7 +8,7 @@ import { MetaTags } from "ol-utilities" import { GridColumn, GridContainer } from "@/components/GridLayout/GridLayout" import { useChannelDetail } from "api/hooks/channels" import EditChannelAppearanceForm from "./EditChannelAppearanceForm" -import { ChannelPageSkeleton } from "./ChannelPageSkeleton" +import { ChannelPageTemplate } from "./ChannelPageTemplate" type RouteParams = { channelType: string name: string @@ -34,7 +34,7 @@ const EditChannelPage: React.FC = () => { ) return channel.data ? ( - @@ -89,7 +89,7 @@ const EditChannelPage: React.FC = () => { )} - + ) : null } diff --git a/frontends/mit-open/src/pages/ChannelPage/UnitChannelSkeleton.tsx b/frontends/mit-open/src/pages/ChannelPage/UnitChannelTemplate.tsx similarity index 96% rename from frontends/mit-open/src/pages/ChannelPage/UnitChannelSkeleton.tsx rename to frontends/mit-open/src/pages/ChannelPage/UnitChannelTemplate.tsx index 5a275d83f4..fdae1a9e80 100644 --- a/frontends/mit-open/src/pages/ChannelPage/UnitChannelSkeleton.tsx +++ b/frontends/mit-open/src/pages/ChannelPage/UnitChannelTemplate.tsx @@ -13,7 +13,7 @@ import { SourceTypeEnum } from "api" import { getSearchParamMap } from "@/common/utils" import { HOME as HOME_URL, UNITS as UNITS_URL } from "../../common/urls" import { ChannelTypeEnum } from "api/v0" -import { ChannelControls, UNITS_LABEL } from "./ChannelPageSkeleton" +import { ChannelControls, UNITS_LABEL } from "./ChannelPageTemplate" const FeaturedCoursesCarousel = styled(ResourceCarousel)(({ theme }) => ({ margin: "80px 0", @@ -23,7 +23,7 @@ const FeaturedCoursesCarousel = styled(ResourceCarousel)(({ theme }) => ({ }, })) -interface UnitChannelSkeletonProps { +interface UnitChannelTemplateProps { children: React.ReactNode name: string } @@ -33,7 +33,7 @@ interface UnitChannelSkeletonProps { * * Renders the channel title and avatar in a banner. */ -const UnitChannelSkeleton: React.FC = ({ +const UnitChannelTemplate: React.FC = ({ children, name, }) => { @@ -181,4 +181,4 @@ const UnitChannelSkeleton: React.FC = ({ ) } -export default UnitChannelSkeleton +export default UnitChannelTemplate From 18a373c2cb9fd2bd3ee8437489fefeab3c74db49 Mon Sep 17 00:00:00 2001 From: Carey Gumaer Date: Tue, 9 Jul 2024 15:00:36 -0400 Subject: [PATCH 14/16] rename subHeader -> subheader --- .../ChannelPage/DefaultChannelTemplate.tsx | 2 +- .../pages/ChannelPage/UnitChannelTemplate.tsx | 6 +++--- .../DepartmentListingPage.tsx | 2 +- .../TopicListingPage/TopicsListingPage.tsx | 2 +- .../UnitsListingPage/UnitsListingPage.tsx | 2 +- .../src/components/Banner/Banner.tsx | 18 +++++++++--------- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/frontends/mit-open/src/pages/ChannelPage/DefaultChannelTemplate.tsx b/frontends/mit-open/src/pages/ChannelPage/DefaultChannelTemplate.tsx index 65f3401ec3..a5614219dc 100644 --- a/frontends/mit-open/src/pages/ChannelPage/DefaultChannelTemplate.tsx +++ b/frontends/mit-open/src/pages/ChannelPage/DefaultChannelTemplate.tsx @@ -110,7 +110,7 @@ const DefaultChannelTemplate: React.FC = ({ ) } header={channel.data?.title} - subHeader={displayConfiguration?.heading} + subheader={displayConfiguration?.heading} extraHeader={displayConfiguration?.sub_heading} backgroundUrl={ displayConfiguration?.banner_background ?? diff --git a/frontends/mit-open/src/pages/ChannelPage/UnitChannelTemplate.tsx b/frontends/mit-open/src/pages/ChannelPage/UnitChannelTemplate.tsx index fdae1a9e80..7e200a0dd9 100644 --- a/frontends/mit-open/src/pages/ChannelPage/UnitChannelTemplate.tsx +++ b/frontends/mit-open/src/pages/ChannelPage/UnitChannelTemplate.tsx @@ -120,9 +120,9 @@ const UnitChannelTemplate: React.FC = ({ header={displayConfiguration?.heading} headerTypography={{ xs: "h5", md: "h4" }} headerStyles={headerStyles} - subHeader={displayConfiguration?.sub_heading} - subHeaderStyles={headerStyles} - subHeaderTypography={{ xs: "body2", md: "body1" }} + subheader={displayConfiguration?.sub_heading} + subheaderStyles={headerStyles} + subheaderTypography={{ xs: "body2", md: "body1" }} extraHeader={ { { /> } header="Browse by Topic" - subHeader="" + subheader="" backgroundUrl={TOPICS_BANNER_IMAGE} /> diff --git a/frontends/mit-open/src/pages/UnitsListingPage/UnitsListingPage.tsx b/frontends/mit-open/src/pages/UnitsListingPage/UnitsListingPage.tsx index 906dd38406..ff376a8258 100644 --- a/frontends/mit-open/src/pages/UnitsListingPage/UnitsListingPage.tsx +++ b/frontends/mit-open/src/pages/UnitsListingPage/UnitsListingPage.tsx @@ -415,7 +415,7 @@ const UnitsListingPage: React.FC = () => { /> } header="Academic & Professional Learning" - subHeader="Non-degree learning resources tailored to the needs of students and working professionals." + subheader="Non-degree learning resources tailored to the needs of students and working professionals." backgroundUrl={UNITS_BANNER_IMAGE} /> diff --git a/frontends/ol-components/src/components/Banner/Banner.tsx b/frontends/ol-components/src/components/Banner/Banner.tsx index 6870c0e8bf..06668ab6ce 100644 --- a/frontends/ol-components/src/components/Banner/Banner.tsx +++ b/frontends/ol-components/src/components/Banner/Banner.tsx @@ -75,9 +75,9 @@ type BannerProps = BannerWrapperProps & { header: React.ReactNode headerTypography?: ResponsiveStyleValue headerStyles?: SxProps - subHeader?: React.ReactNode - subHeaderTypography?: ResponsiveStyleValue - subHeaderStyles?: SxProps + subheader?: React.ReactNode + subheaderTypography?: ResponsiveStyleValue + subheaderStyles?: SxProps extraHeader?: React.ReactNode extraRight?: React.ReactNode } @@ -96,9 +96,9 @@ const Banner = ({ header, headerTypography, headerStyles, - subHeader, - subHeaderTypography, - subHeaderStyles, + subheader, + subheaderTypography, + subheaderStyles, extraHeader, extraRight, }: BannerProps) => { @@ -125,10 +125,10 @@ const Banner = ({ - {subHeader} + {subheader}
{extraHeader}
From 71dbe23cb4f27a45f556204bf80327e242153abf Mon Sep 17 00:00:00 2001 From: Carey Gumaer Date: Tue, 9 Jul 2024 15:39:08 -0400 Subject: [PATCH 15/16] add new banner stories --- .../src/components/Banner/Banner.stories.tsx | 83 +++++++++++++++++-- 1 file changed, 78 insertions(+), 5 deletions(-) diff --git a/frontends/ol-components/src/components/Banner/Banner.stories.tsx b/frontends/ol-components/src/components/Banner/Banner.stories.tsx index f145eae1be..59e2922190 100644 --- a/frontends/ol-components/src/components/Banner/Banner.stories.tsx +++ b/frontends/ol-components/src/components/Banner/Banner.stories.tsx @@ -1,21 +1,94 @@ +import React from "react" import type { Meta, StoryObj } from "@storybook/react" +import { withRouter } from "storybook-addon-react-router-v6" import { Banner } from "./Banner" +import { Breadcrumbs } from "../Breadcrumbs/Breadcrumbs" +import { Button } from "../Button/Button" +import Typography from "@mui/material/Typography" const lipsum = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista probare, quae sunt a te dicta? Refert tamen, quo modo" -const meta: Meta = { +const meta: Meta = { title: "smoot-design/Banner", component: Banner, args: { backgroundUrl: "https://images.pexels.com/photos/1851188/pexels-photo-1851188.jpeg?auto=compress&cs=tinysrgb&w=800", - title: "Banner Title", - description: lipsum, - navText: "Home / Nav / Text", + navText: ( + + ), + header: "Banner Title", + subheader: lipsum, }, } export default meta type Story = StoryObj -export const story: Story = {} + +export const basicBanner: Story = { + decorators: [withRouter], + render: (args) => , +} + +export const logoBanner: Story = { + decorators: [withRouter], + render: (args) => { + return ( + + } + {...args} + /> + ) + }, +} + +export const logoBannerWithExtras: Story = { + decorators: [withRouter], + render: (args) => { + return ( + + } + extraHeader={ + + } + extraRight={ +
+ Extra Content +
+ +
+
+ +
+
+ } + {...args} + /> + ) + }, +} From a75ba6b268f35ff7f99fbe109a5d3ff4d6851615 Mon Sep 17 00:00:00 2001 From: Carey Gumaer Date: Tue, 9 Jul 2024 16:05:49 -0400 Subject: [PATCH 16/16] fix issue with wrapping breadcrumbs on mobile --- .../Breadcrumbs/Breadcrumbs.test.tsx | 2 +- .../components/Breadcrumbs/Breadcrumbs.tsx | 23 +++++++++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/frontends/ol-components/src/components/Breadcrumbs/Breadcrumbs.test.tsx b/frontends/ol-components/src/components/Breadcrumbs/Breadcrumbs.test.tsx index f2cbfcc1f6..44b8c28159 100644 --- a/frontends/ol-components/src/components/Breadcrumbs/Breadcrumbs.test.tsx +++ b/frontends/ol-components/src/components/Breadcrumbs/Breadcrumbs.test.tsx @@ -46,7 +46,7 @@ describe("Breadcrumbs", () => { ) expect(screen.getAllByRole("link")).toHaveLength(totalAncestors) expectedLabels.forEach((label, index) => { - const link = screen.getByText(label) + const link = screen.getByText(label).parentElement expect(link).toBeInTheDocument() expect(link).toHaveAttribute("href", expectedHrefs[index]) }) diff --git a/frontends/ol-components/src/components/Breadcrumbs/Breadcrumbs.tsx b/frontends/ol-components/src/components/Breadcrumbs/Breadcrumbs.tsx index 8389b5fb61..60c7f1ec7b 100644 --- a/frontends/ol-components/src/components/Breadcrumbs/Breadcrumbs.tsx +++ b/frontends/ol-components/src/components/Breadcrumbs/Breadcrumbs.tsx @@ -8,11 +8,26 @@ const BreadcrumbsContainer = styled.span({ display: "inline-flex", paddingBottom: "16px", alignItems: "flex-start", + overflow: "hidden", + width: "100%", }) const Breadcrumb = styled.span({ display: "flex", alignItems: "center", + overflow: "hidden", +}) + +const BreadcrumbLink = styled(Link)({ + overflow: "hidden", + textOverflow: "ellipsis", +}) + +const BreadcrumbText = styled.span({ + textWrap: "nowrap", + whiteSpace: "nowrap", + overflow: "hidden", + textOverflow: "ellipsis", }) const Separator = styled(RiArrowRightSLine)({ @@ -28,7 +43,7 @@ const DarkSeparator = styled(Separator)({ color: theme.custom.colors.silverGray, }) -const Current = styled.span({ +const Current = styled(BreadcrumbText)({ ...theme.typography.body3, }) @@ -57,14 +72,14 @@ const Breadcrumbs: React.FC = (props) => { const isLast = index === ancestors.length return ( - - {ancestor.label} - + {ancestor.label} + {!isLast && <_Separator data-testid="breadcrumb-separator" />} )