diff --git a/frontends/main/public/images/backgrounds/open-bg-texture-with-gradient.svg b/frontends/main/public/images/backgrounds/open-bg-texture-with-gradient.svg new file mode 100644 index 0000000000..f17f0d9076 --- /dev/null +++ b/frontends/main/public/images/backgrounds/open-bg-texture-with-gradient.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/frontends/main/src/app-pages/HomePage/BrowseTopicsSection.tsx b/frontends/main/src/app-pages/HomePage/BrowseTopicsSection.tsx index d26046b909..245c905101 100644 --- a/frontends/main/src/app-pages/HomePage/BrowseTopicsSection.tsx +++ b/frontends/main/src/app-pages/HomePage/BrowseTopicsSection.tsx @@ -13,7 +13,7 @@ import { RiArrowRightLine } from "@remixicon/react" import RootTopicIcon from "@/components/RootTopicIcon/RootTopicIcon" const Section = styled.section` - background: #fff url("/static/images/open-bg-texture-with-gradient.svg") + background: #fff url("/images/backgrounds/open-bg-texture-with-gradient.svg") no-repeat center left; background-size: 135% auto; padding: 80px 0; diff --git a/frontends/main/src/app-pages/HomePage/TestimonialsSection.tsx b/frontends/main/src/app-pages/HomePage/TestimonialsSection.tsx index e7a4d0226a..db009a3beb 100644 --- a/frontends/main/src/app-pages/HomePage/TestimonialsSection.tsx +++ b/frontends/main/src/app-pages/HomePage/TestimonialsSection.tsx @@ -1,4 +1,4 @@ -import React from "react" +import React, { useEffect, useState } from "react" import _ from "lodash" import { Container, @@ -11,11 +11,11 @@ import { onReInitSlickA11y, } from "ol-components" import { useTestimonialList } from "api/hooks/testimonials" +import type { Attestation } from "api/v0" import { RiArrowRightLine, RiArrowLeftLine } from "@remixicon/react" import Slider from "react-slick" import AttestantBlock from "@/page-components/TestimonialDisplay/AttestantBlock" - -const MARKETING_IMAGE_IDX = _.shuffle([1, 2, 3, 4, 5, 6]) +import Image from "next/image" const HeaderContainer = styled(Container)(({ theme }) => ({ display: "flex", @@ -224,8 +224,18 @@ const TestimonialTruncateText = styled(TruncateText)({ const SlickCarousel = () => { const { data } = useTestimonialList({ position: 1 }) const [slick, setSlick] = React.useState(null) + const [shuffled, setShuffled] = useState() + const [imageSequence, setImageSequence] = useState() + + useEffect(() => { + if (!data) return + setShuffled(_.shuffle(data?.results)) + setImageSequence(_.shuffle([1, 2, 3, 4, 5, 6])) + }, [data]) - if (!data || data.results.length === 0) return null + if (!data?.results?.length || !shuffled?.length) { + return null + } const settings = { ref: setSlick, @@ -248,7 +258,7 @@ const SlickCarousel = () => { return ( - {_.shuffle(data?.results).map((resource, idx) => ( + {shuffled.map((resource, idx) => ( { className="testimonial-card" > - diff --git a/frontends/main/src/page-components/HeroSearch/HeroSearch.tsx b/frontends/main/src/page-components/HeroSearch/HeroSearch.tsx index efecdf70a2..bf68532232 100644 --- a/frontends/main/src/page-components/HeroSearch/HeroSearch.tsx +++ b/frontends/main/src/page-components/HeroSearch/HeroSearch.tsx @@ -1,6 +1,6 @@ "use client" -import React, { useState, useCallback } from "react" +import React, { useState, useCallback, useEffect } from "react" import { useRouter } from "next/navigation" import { Typography, @@ -27,7 +27,6 @@ import { RiTimeLine, RiVerifiedBadgeLine, } from "@remixicon/react" -import _ from "lodash" import { NON_DEGREE_LEARNING_FRAGMENT_IDENTIFIER } from "@/app-pages/AboutPage/AboutPage" import Image from "next/image" @@ -111,6 +110,7 @@ const ImageContainer = styled.div(({ theme }) => ({ img: { width: "100%", }, + position: "relative", })) const ControlsContainer = styled.div(({ theme }) => ({ @@ -192,16 +192,30 @@ const BoldLink = styled(Link)(({ theme }) => ({ ...theme.typography.subtitle1, })) -const getRandomHeroImage = () => { - const imageNumber = _.shuffle([1, 2, 3, 4, 5])[0] - return `/images/hero/hero-${imageNumber}.png` -} - const HeroImage: React.FC = () => { - const [heroImage, _] = useState(getRandomHeroImage) + const [imageIndex, setImageIndex] = useState() + + useEffect(() => { + /* We need to set the random image index once in useEffece to prevent + * hydration mismatch between client and server + */ + const index = Math.floor(Math.random() * 5) + 1 + setImageIndex(index) + }, []) + + if (!imageIndex) { + return + } + return ( - + ) }