Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@ import { RiAccountCircleFill } from "@remixicon/react"
import { TruncateText, styled, theme } from "ol-components"
import type { Attestation } from "api/v0"

type AttestantBlockVariant = "start" | "end"
type AttestantAvatarPosition = "start" | "end"
type AttestantBlockColor = "light" | "dark"
type AttestantAvatarStyle = "homepage" | "unit"
type AttestantBlockVariant = "standard" | "condensed"

type AttestantBlockChildProps = {
variant?: AttestantBlockVariant
avatarPosition?: AttestantAvatarPosition
avatarStyle?: AttestantAvatarStyle
color?: AttestantBlockColor
avatar?: AttestantAvatarStyle
variant?: AttestantBlockVariant
}

type AttestantBlockProps = AttestantBlockChildProps & {
Expand All @@ -26,20 +28,20 @@ const StyledRiAccountCircleFill = styled(RiAccountCircleFill)({

const AttestantBlockContainer = styled.cite<AttestantBlockChildProps>(
(props) => {
const flexDir = props.variant === "end" ? "row-reverse" : "row"
const flexDir = props.avatarPosition === "end" ? "row-reverse" : "row"

return [
{
display: "flex",
flexShrink: 0,
flexDirection: flexDir,
width: props.variant === "end" ? "100%" : "300px",
marginLeft: props.variant === "end" ? "0px" : "24px",
width: props.avatarPosition === "end" ? "100%" : "300px",
marginLeft: props.avatarPosition === "end" ? "0px" : "24px",
...theme.typography.body3,
[theme.breakpoints.down("sm")]: {
width: "100%",
height: "56px",
marginTop: props.variant === "end" ? "0px" : "24px",
marginTop: props.avatarPosition === "end" ? "0px" : "24px",
marginLeft: "0px",
},
},
Expand All @@ -50,8 +52,8 @@ const AttestantBlockContainer = styled.cite<AttestantBlockChildProps>(
const AttestantAvatar = styled.div<AttestantBlockChildProps>((props) => {
return [
{
marginRight: props.variant === "end" ? "0px" : "12px",
marginLeft: props.variant === "end" ? "14px" : "0px",
marginRight: props.avatarPosition === "end" ? "0px" : "12px",
marginLeft: props.avatarPosition === "end" ? "14px" : "0px",
img: {
objectFit: "cover",
borderRadius: "50%",
Expand All @@ -62,7 +64,7 @@ const AttestantAvatar = styled.div<AttestantBlockChildProps>((props) => {
"0px 2px 4px 0px rgba(37, 38, 43, 0.10), 0px 2px 4px 0px rgba(37, 38, 43, 0.10)",
},
[theme.breakpoints.down("sm")]: {
display: props.avatar === "homepage" ? "none" : "block",
display: props.avatarStyle === "homepage" ? "none" : "block",
},
},
]
Expand All @@ -73,7 +75,7 @@ const AttestantNameBlock = styled.div<AttestantBlockChildProps>((props) => {
{
flexGrow: "1",
width: "auto",
textAlign: props.variant === "end" ? "end" : "start",
textAlign: props.avatarPosition === "end" ? "end" : "start",
color:
props.color === "light"
? theme.custom.colors.lightGray2
Expand All @@ -83,39 +85,76 @@ const AttestantNameBlock = styled.div<AttestantBlockChildProps>((props) => {
})

const AttestantName = styled.div<AttestantBlockChildProps>((props) => {
const desktopFont =
props.variant === "standard"
? theme.typography.h5
: theme.typography.subtitle1
return [
{
...theme.typography.subtitle1,
...desktopFont,
whiteSpace: "nowrap",
color:
props.color === "light"
? theme.custom.colors.white
: theme.custom.colors.darkGray2,
lineHeight: "125%",
[theme.breakpoints.down("sm")]: {
...theme.typography.subtitle1,
},
},
]
})

const AttestantTitle = styled.div<AttestantBlockChildProps>((props) => {
const desktopFont =
props.variant === "standard"
? theme.typography.body1
: theme.typography.body3
return [
{
...desktopFont,
color:
props.color === "light"
? theme.custom.colors.lightGray2
: theme.custom.colors.silverGrayDark,
[theme.breakpoints.down("sm")]: {
...theme.typography.body2,
},
},
]
})

const AttestantBlock: React.FC<AttestantBlockProps> = ({
attestation,
variant = "start",
avatarPosition = "start",
avatarStyle: avatar = "unit",
color = "light",
avatar = "unit",
variant = "standard",
}) => {
return (
<AttestantBlockContainer variant={variant} color={color}>
<AttestantAvatar variant={variant} color={color} avatar={avatar}>
<AttestantBlockContainer avatarPosition={avatarPosition} color={color}>
<AttestantAvatar
avatarPosition={avatarPosition}
color={color}
avatarStyle={avatar}
>
{attestation.avatar_medium ? (
<img src={attestation.avatar_medium} alt="" />
) : (
<StyledRiAccountCircleFill />
)}
</AttestantAvatar>
<AttestantNameBlock variant={variant} color={color}>
<AttestantName variant={variant} color={color}>
<AttestantNameBlock avatarPosition={avatarPosition} color={color}>
<AttestantName
avatarPosition={avatarPosition}
color={color}
variant={variant}
>
{attestation?.attestant_name}
</AttestantName>
<TruncateText lineClamp={2}>{attestation.title}</TruncateText>
<AttestantTitle variant={variant}>
<TruncateText lineClamp={2}>{attestation.title}</TruncateText>
</AttestantTitle>
</AttestantNameBlock>
</AttestantBlockContainer>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ import type { Attestation } from "api/v0"
type TestimonialDisplayProps = {
channels?: number[]
offerors?: string[]
variant?: "standard" | "condensed"
}

type InternalTestimonialDisplayProps = {
attestation: Attestation
variant?: "standard" | "condensed"
}

const TestimonialTruncateText = styled(TruncateText)({
Expand Down Expand Up @@ -110,6 +112,7 @@ const NoButtonsContainer = styled(ButtonsContainer)({

const InteriorTestimonialDisplay: React.FC<InternalTestimonialDisplayProps> = ({
attestation,
variant = "standard",
}) => {
return (
<QuoteBody>
Expand All @@ -119,14 +122,19 @@ const InteriorTestimonialDisplay: React.FC<InternalTestimonialDisplayProps> = ({
{attestation?.quote.length >= 350 ? "..." : null}
</TestimonialTruncateText>
</AttestationBlock>
<AttestantBlock attestation={attestation} variant="start" />
<AttestantBlock
attestation={attestation}
avatarPosition="start"
variant={variant}
/>
</QuoteBody>
)
}

const TestimonialDisplay: React.FC<TestimonialDisplayProps> = ({
channels,
offerors,
variant = "standard",
}) => {
const { data } = useTestimonialList({
channels: channels,
Expand Down Expand Up @@ -165,6 +173,7 @@ const TestimonialDisplay: React.FC<TestimonialDisplayProps> = ({
<InteriorTestimonialDisplay
key={`testimonial-${attestation.id}`}
attestation={attestation}
variant={variant}
></InteriorTestimonialDisplay>
))}
</Slider>
Expand Down Expand Up @@ -192,6 +201,7 @@ const TestimonialDisplay: React.FC<TestimonialDisplayProps> = ({
<InteriorTestimonialDisplay
key={`testimonial-${data["results"][0].id}`}
attestation={data["results"][0]}
variant={variant}
></InteriorTestimonialDisplay>
<NoButtonsContainer></NoButtonsContainer>
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ const UnitChannelTemplate: React.FC<UnitChannelTemplateProps> = ({
</Container>
<section>
<VisuallyHidden as="h2">What Learners Say</VisuallyHidden>
<TestimonialDisplay offerors={[name]} />
<TestimonialDisplay offerors={[name]} variant="condensed" />
</section>
<Container>{children}</Container>
</>
Expand Down
24 changes: 18 additions & 6 deletions frontends/mit-learn/src/pages/HomePage/TestimonialsSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,18 @@ import AttestantBlock from "@/page-components/TestimonialDisplay/AttestantBlock"

const MARKETING_IMAGE_IDX = _.shuffle([1, 2, 3, 4, 5, 6])

const HeaderContainer = styled(Container)(({ theme }) => ({
display: "flex",
flexDirection: "column",
alignItems: "center",
textAlign: "center",
gap: "8px",
paddingBottom: "60px",
[theme.breakpoints.down("md")]: {
paddingBottom: "28px",
},
}))

const Section = styled.section(({ theme }) => ({
backgroundColor: theme.custom.colors.mitRed,
color: theme.custom.colors.white,
Expand Down Expand Up @@ -262,9 +274,9 @@ const SlickCarousel = () => {
</TestimonialTruncateText>
<AttestantBlock
attestation={resource}
variant="end"
avatarPosition="end"
color="dark"
avatar="homepage"
avatarStyle="homepage"
/>
</TestimonialCardQuote>
</TestimonialCard>
Expand Down Expand Up @@ -296,15 +308,15 @@ const SlickCarousel = () => {
const TestimonialsSection: React.FC = () => {
return (
<Section>
<Container id="hamster-noises">
<Typography component="h2" variant="h2">
<HeaderContainer>
<Typography component="h2" typography={{ xs: "h3", sm: "h2" }}>
From Our Community
</Typography>
<Typography variant="h3">
<Typography variant="body1">
Millions of learners are reaching their goals with MIT's non-degree
learning resources. Here's what they're saying.
</Typography>
Comment on lines +315 to 318
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at figma, I guess this should have textAlign: center.

Could be styled(...), or Typography has a prop for that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The HeaderContainer styled component handles this with alignItems: "center", do we really need a duplicate centering rule?

Copy link
Contributor

@ChristopherChudzicki ChristopherChudzicki Sep 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not duplicate, they do different things.

  • align-items: center aligns the purple box within the blue box
  • text-align: center justifies the text at center instead of left

Note: I set the width of the purple box to illustrate the effect. Currently the effect is really only visible on mobile

Screenshot 2024-09-17 at 4 18 56 PM

</Container>
</HeaderContainer>
<SlickCarousel />
</Section>
)
Expand Down