@@ -8,33 +8,48 @@ import {
88 BannerBackground ,
99 Typography ,
1010 HEADER_HEIGHT ,
11+ Grid2 ,
1112} from "ol-components"
1213import { convertToEmbedUrl } from "@/common/utils"
13- import { backgroundSrcSetCSS } from "ol-utilities"
1414import { HOME } from "@/common/urls"
15- import backgroundSteps from "@/public/images/backgrounds/background_steps.jpg"
1615import { styled } from "@mitodl/smoot-design"
1716import Image from "next/image"
1817import type { Breakpoint } from "@mui/system"
1918
20- const StyledBreadcrumbs = styled ( Breadcrumbs ) ( ( { theme } ) => ( {
21- paddingBottom : "24px" ,
22- [ theme . breakpoints . down ( "md" ) ] : {
23- paddingBottom : "16px" ,
19+ const GradientBanner = styled ( BannerBackground ) ( ( { theme } ) => ( {
20+ background :
21+ "radial-gradient(53.28% 106.57% at 50% 14.6%, #1D7B83 0%, #1E1E54 100%)" ,
22+ padding : 0 ,
23+ [ theme . breakpoints . down ( "sm" ) ] : {
24+ padding : 0 ,
25+ } ,
26+ } ) )
27+
28+ const StyledBreadcrumbs = styled ( Breadcrumbs ) ( ( ) => ( {
29+ "& > span" : {
30+ paddingBottom : 0 ,
2431 } ,
2532} ) )
2633
2734const TitleBox = styled ( Stack ) ( ( { theme } ) => ( {
2835 color : theme . custom . colors . white ,
2936} ) )
30- const ProductTag = styled . div ( ( { theme } ) => ( {
31- backgroundColor : theme . custom . colors . darkGray1 ,
32- display : "flex" ,
33- alignItems : "center" ,
34- justifyContent : "center" ,
35- padding : "4px 12px" ,
36- borderRadius : "4px" ,
37- ...theme . typography . subtitle2 ,
37+
38+ const ContentStack = styled ( Stack ) ( ( { theme } ) => ( {
39+ gap : "32px" ,
40+ marginTop : "16px" ,
41+ [ theme . breakpoints . down ( "md" ) ] : {
42+ gap : "16px" ,
43+ marginTop : 0 ,
44+ } ,
45+ } ) )
46+
47+ const EnrollButton = styled . div ( ( { theme } ) => ( {
48+ width : "240px" ,
49+
50+ [ theme . breakpoints . down ( "sm" ) ] : {
51+ width : "100%" ,
52+ } ,
3853} ) )
3954
4055const Page = styled . div ( ( { theme } ) => ( {
@@ -46,11 +61,16 @@ const Page = styled.div(({ theme }) => ({
4661 height : "100%" ,
4762} ) )
4863
49- const TopContainer = styled ( Container ) ( {
50- display : "flex" ,
51- justifyContent : "space-between" ,
52- gap : "56px" ,
53- } )
64+ const TopContainer = styled ( Container ) ( ( { theme } ) => ( {
65+ padding : "104px 0" ,
66+
67+ [ theme . breakpoints . down ( "md" ) ] : {
68+ padding : "64px 40px" ,
69+ } ,
70+ [ theme . breakpoints . down ( "sm" ) ] : {
71+ padding : "32px 24px" ,
72+ } ,
73+ } ) )
5474const BottomContainer = styled ( Container ) ( ( { theme } ) => ( {
5575 display : "flex" ,
5676 justifyContent : "space-between" ,
@@ -91,7 +111,6 @@ const Show = styled("div", {
91111
92112const MainCol = styled . div ( {
93113 width : "100%" ,
94- flex : 1 ,
95114 minWidth : 0 ,
96115 display : "flex" ,
97116 flexDirection : "column" ,
@@ -115,7 +134,6 @@ const SidebarCol = styled(Show, {
115134 alignSelf ?: React . CSSProperties [ "alignSelf" ]
116135} > ( ( { alignSelf } ) => ( {
117136 width : "100%" ,
118- maxWidth : "410px" ,
119137 alignSelf,
120138} ) )
121139
@@ -144,28 +162,40 @@ const SummaryCol = styled.div(({ theme }) => ({
144162} ) )
145163
146164const SidebarVideo = styled . iframe ( ( { theme } ) => ( {
147- borderRadius : "4px " ,
165+ borderRadius : "16px " ,
148166 border : "none" ,
149- width : "100% " ,
167+ boxShadow : "0 0 48.4px 0 rgba(0, 0, 0, 0.50) " ,
150168 maxWidth : "410px" ,
151- aspectRatio : "410 / 230" ,
152- display : "block" ,
169+ width : "100%" ,
170+ aspectRatio : "16 / 9" ,
171+ [ theme . breakpoints . up ( "md" ) ] : {
172+ position : "sticky" ,
173+ // Without this, the flex child stretches to the main column's height
174+ // and sticky has no room to scroll.
175+ alignSelf : "flex-start" ,
176+ top : `${ HEADER_HEIGHT + OFFSET_FROM_HEADER } px` ,
177+ } ,
153178 [ theme . breakpoints . down ( "md" ) ] : {
154- border : `1px solid ${ theme . custom . colors . lightGray2 } ` ,
155- borderRadius : "4px 4px 0 0" ,
179+ maxWidth : "none" ,
156180 } ,
157181} ) )
158182
159183const SidebarImage = styled ( Image ) ( ( { theme } ) => ( {
160- borderRadius : "4px" ,
184+ borderRadius : "16px" ,
185+ boxShadow : "0 0 48.4px 0 rgba(0, 0, 0, 0.50)" ,
161186 width : "100%" ,
162- maxWidth : "410px" ,
163- aspectRatio : "410 / 230" ,
187+ aspectRatio : "16/9" ,
164188 height : "auto" ,
165189 display : "block" ,
166- [ theme . breakpoints . down ( "md" ) ] : {
167- border : `1px solid ${ theme . custom . colors . lightGray2 } ` ,
168- borderRadius : "4px 4px 0 0" ,
190+ [ theme . breakpoints . down ( "sm" ) ] : {
191+ maxWidth : "100%" ,
192+ } ,
193+ } ) )
194+
195+ const ShortDescription = styled ( Typography ) ( ( { theme } ) => ( {
196+ ...theme . typography . body1 ,
197+ [ theme . breakpoints . down ( "sm" ) ] : {
198+ ...theme . typography . body2 ,
169199 } ,
170200} ) )
171201
@@ -186,70 +216,83 @@ const SidebarMedia: React.FC<{
186216 return (
187217 < SidebarImage
188218 priority = { priority }
189- width = { 410 }
190- height = { 230 }
219+ width = { 540 }
220+ height = { 306 }
191221 src = { imageSrc }
192222 alt = ""
193223 />
194224 )
195225}
196226
197227type ProductPageTemplateProps = {
198- tags : string [ ]
199228 currentBreadcrumbLabel : string
200229 title : string
201230 shortDescription : React . ReactNode
202231 imageSrc : string
203232 videoUrl ?: string | null
204233 infoBox : React . ReactNode
234+ enrollmentAction : React . ReactNode
205235 children : React . ReactNode
206236}
207237const ProductPageTemplate : React . FC < ProductPageTemplateProps > = ( {
208- tags,
209238 currentBreadcrumbLabel,
210239 title,
211240 shortDescription,
212241 imageSrc,
213242 videoUrl,
214243 infoBox,
215244 children,
245+ enrollmentAction,
216246} ) => {
217247 return (
218248 < Page >
219- < BannerBackground backgroundUrl = { backgroundSrcSetCSS ( backgroundSteps ) } >
249+ < GradientBanner >
220250 < TopContainer data-testid = "banner-container" >
221- < MainCol >
222- < StyledBreadcrumbs
223- variant = "dark"
224- ancestors = { [ { href : HOME , label : "Home" } ] }
225- current = { currentBreadcrumbLabel }
226- />
227- < TitleBox alignItems = "flex-start" gap = "4px" >
228- < Stack direction = "row" gap = "8px" >
229- { tags . map ( ( tag ) => {
230- return < ProductTag key = { tag } > { tag } </ ProductTag >
231- } ) }
232- </ Stack >
233- < Stack alignItems = "flex-start" gap = "16px" >
234- < Typography component = "h1" typography = { { xs : "h3" , sm : "h2" } } >
235- { title }
236- </ Typography >
237- < Typography typography = { { xs : "body2" , sm : "body1" } } >
238- { shortDescription }
239- </ Typography >
240- </ Stack >
241- </ TitleBox >
242- </ MainCol >
243- < SidebarCol showAbove = "md" alignSelf = "flex-end" >
244- < SidebarMedia
245- videoUrl = { videoUrl }
246- imageSrc = { imageSrc }
247- title = { title }
248- priority
249- />
250- </ SidebarCol >
251+ < Grid2 container spacing = { { xs : 2 , sm : 2 , md : 8 } } >
252+ < Grid2 size = { { xs : 12 , sm : 6 , md : 7 } } >
253+ < MainCol >
254+ < StyledBreadcrumbs
255+ variant = "dark"
256+ ancestors = { [ { href : HOME , label : "Home" } ] }
257+ current = { currentBreadcrumbLabel }
258+ />
259+ < TitleBox alignItems = "flex-start" gap = "4px" >
260+ < ContentStack alignItems = "flex-start" >
261+ < SidebarCol showBelow = "sm" alignSelf = "flex-end" >
262+ < SidebarMedia
263+ videoUrl = { videoUrl }
264+ imageSrc = { imageSrc }
265+ title = { title }
266+ />
267+ </ SidebarCol >
268+ < Typography
269+ component = "h1"
270+ typography = { { xs : "h4" , sm : "h4" , md : "h4" } }
271+ >
272+ { title }
273+ </ Typography >
274+ < ShortDescription > { shortDescription } </ ShortDescription >
275+ < EnrollButton > { enrollmentAction } </ EnrollButton >
276+ </ ContentStack >
277+ </ TitleBox >
278+ </ MainCol >
279+ </ Grid2 >
280+ < Grid2
281+ size = { { xs : 12 , sm : 6 , md : 5 } }
282+ style = { { display : "flex" , alignSelf : "center" } }
283+ >
284+ < SidebarCol showAbove = "sm" alignSelf = "flex-end" >
285+ < SidebarMedia
286+ videoUrl = { videoUrl }
287+ imageSrc = { imageSrc }
288+ title = { title }
289+ priority
290+ />
291+ </ SidebarCol >
292+ </ Grid2 >
293+ </ Grid2 >
251294 </ TopContainer >
252- </ BannerBackground >
295+ </ GradientBanner >
253296 < BottomContainer >
254297 < SummaryCol > { infoBox } </ SummaryCol >
255298 < MainCol >
0 commit comments