Skip to content

Commit

Permalink
(PC-33792) feat(MarketingBlockExclusivity): coming soon
Browse files Browse the repository at this point in the history
  • Loading branch information
nmajorfrances-pass committed Jan 14, 2025
1 parent 124a56c commit 5e56656
Show file tree
Hide file tree
Showing 11 changed files with 207 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,21 @@ const variantConfig: Variants<typeof AttachedCardDisplay> = [
),
},
},
{
label: 'AttachedCardDisplay with coming soon info',
props: {
bottomBannerText: 'Disponible le 17 février',
details: ['Du 12/06 au 24/06', 'Duo'],
LeftImageComponent: () => (
<OfferImage
imageUrl="https://storage.googleapis.com/passculture-metier-prod-production-assets-fine-grained/thumbs/mediations/9MPGW"
categoryId={CategoryIdEnum.BEAUX_ARTS}
borderRadius={5}
withStroke
/>
),
},
},
]

const Template: VariantsStory<typeof AttachedCardDisplay> = (args) => (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react'
import styled from 'styled-components/native'

import { OfferName } from 'ui/components/tiles/OfferName'
import { ClockFilled } from 'ui/svg/icons/ClockFilled'
import { getSpacing, Spacer, TypoDS } from 'ui/theme'

interface AttachedCardDisplayProps {
Expand All @@ -13,11 +14,13 @@ interface AttachedCardDisplayProps {
bottomRightElement?: React.ReactNode
accessibilityLabel?: string
shouldFixHeight?: boolean
bottomBannerText?: string
}

const BORDER_WIDTH = getSpacing(0.25)
const OFFER_CARD_HEIGHT = getSpacing(25)
const OFFER_CARD_PADDING = getSpacing(4)
const BORDER_RADIUS = getSpacing(3)

export const AttachedCardDisplay: React.FC<AttachedCardDisplayProps> = ({
title,
Expand All @@ -27,40 +30,68 @@ export const AttachedCardDisplay: React.FC<AttachedCardDisplayProps> = ({
rightTagLabel,
bottomRightElement,
accessibilityLabel,
bottomBannerText,
shouldFixHeight = false,
}: AttachedCardDisplayProps) => {
return (
<Container accessibilityLabel={accessibilityLabel} shouldFixHeight={shouldFixHeight}>
{LeftImageComponent ? (
<ImageContainer>
<LeftImageComponent />
</ImageContainer>
) : null}
<CentralColumn>
{subtitle ? <TypoDS.BodyAccentXs>{subtitle}</TypoDS.BodyAccentXs> : null}
<OfferName title={title} />
{details
? details?.map((detail) => <CaptionNeutralInfo key={detail}>{detail}</CaptionNeutralInfo>)
: null}
</CentralColumn>
<RightColumn>
{rightTagLabel ? (
<TagWrapper label={rightTagLabel}>
<TypoDS.BodyAccentXs>{rightTagLabel}</TypoDS.BodyAccentXs>
</TagWrapper>
) : null}
<Spacer.Flex />
{bottomRightElement ? (
<React.Fragment>
<Container
accessibilityLabel={accessibilityLabel}
shouldFixHeight={shouldFixHeight}
bottomBannerText={bottomBannerText}>
{LeftImageComponent ? (
<React.Fragment>
<Spacer.Row numberOfSpaces={1} />
{bottomRightElement}
<ImageContainer>
<LeftImageComponent />
</ImageContainer>
</React.Fragment>
) : null}
</RightColumn>
</Container>
<CentralColumn>
{subtitle ? <TypoDS.BodyAccentXs>{subtitle}</TypoDS.BodyAccentXs> : null}
<OfferName title={title} />
{details
? details?.map((detail) => (
<CaptionNeutralInfo key={detail}>{detail}</CaptionNeutralInfo>
))
: null}
</CentralColumn>
<RightColumn>
{rightTagLabel ? (
<TagWrapper label={rightTagLabel}>
<TypoDS.BodyAccentXs>{rightTagLabel}</TypoDS.BodyAccentXs>
</TagWrapper>
) : null}
<Spacer.Flex />
{bottomRightElement ? (
<React.Fragment>
<Spacer.Row numberOfSpaces={1} />
{bottomRightElement}
</React.Fragment>
) : null}
</RightColumn>
</Container>
{bottomBannerText ? (
<BottomBanner testId="bottom-banner">
<ClockFilled />
<TypoDS.BodyAccentXs>{bottomBannerText}</TypoDS.BodyAccentXs>
</BottomBanner>
) : null}
</React.Fragment>
)
}

const BottomBanner = styled.View(({ theme }) => ({
paddingHorizontal: getSpacing(4),
paddingVertical: getSpacing(2),
height: getSpacing(10),
gap: getSpacing(2),
backgroundColor: theme.colors.goldLight200,
borderBottomLeftRadius: BORDER_RADIUS,
borderBottomRightRadius: BORDER_RADIUS,
flexDirection: 'row',
alignItems: 'center',
}))

const TagWrapper = styled.View(({ theme }) => ({
borderRadius: theme.tiles.borderRadius,
backgroundColor: theme.colors.greyLight,
Expand All @@ -87,17 +118,22 @@ const ImageContainer = styled.View({
justifyContent: 'center',
})

const Container = styled.View<{ shouldFixHeight: boolean }>(({ theme, shouldFixHeight }) => ({
backgroundColor: theme.colors.white,
borderRadius: getSpacing(3),
borderWidth: BORDER_WIDTH,
borderColor: theme.colors.greyMedium,
gap: getSpacing(2),
flexDirection: 'row',
padding: OFFER_CARD_PADDING,
flexWrap: 'wrap',
height: shouldFixHeight ? OFFER_CARD_HEIGHT + 2 * OFFER_CARD_PADDING : 'auto',
}))
const Container = styled.View<{ shouldFixHeight: boolean; bottomBannerText: string }>(
({ theme, shouldFixHeight, bottomBannerText }) => ({
backgroundColor: theme.colors.white,
borderTopLeftRadius: BORDER_RADIUS,
borderTopRightRadius: BORDER_RADIUS,
borderBottomLeftRadius: bottomBannerText ? 0 : BORDER_RADIUS,
borderBottomRightRadius: bottomBannerText ? 0 : BORDER_RADIUS,
borderWidth: BORDER_WIDTH,
borderColor: theme.colors.greyMedium,
gap: getSpacing(2),
flexDirection: 'row',
padding: OFFER_CARD_PADDING,
flexWrap: 'wrap',
height: shouldFixHeight ? OFFER_CARD_HEIGHT + 2 * OFFER_CARD_PADDING : 'auto',
})
)

const CaptionNeutralInfo = styled(TypoDS.BodyAccentXs)(({ theme }) => ({
color: theme.colors.greyDark,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,20 @@ describe('AttachedOfferCard', () => {

it('should display price if offer has one', () => {
render(<AttachedOfferCard offer={offer} />)

const price = screen.getByText('Dès 34 €')

expect(price).toBeOnTheScreen()
})

it('should display bottomBannerText if offer has one', () => {
render(<AttachedOfferCard offer={offer} comingSoon="Disponible le 17 février" />)

const comingSoon = screen.getByText('Disponible le 17 février')

expect(comingSoon).toBeOnTheScreen()
})

it('should have accessibility label', () => {
render(<AttachedOfferCard offer={offer} />)
const accessibilityLabel = screen.getByLabelText(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ import { OfferImage } from 'ui/components/tiles/OfferImage'
type Props = {
offer: Offer
shouldFixHeight?: boolean
comingSoon?: string
}

export const AttachedOfferCard: React.FC<Props> = ({ offer, shouldFixHeight }) => {
export const AttachedOfferCard: React.FC<Props> = ({ offer, shouldFixHeight, comingSoon }) => {
const { offer: attachedOffer } = offer
const { user } = useAuthContext()
const mapping = useCategoryIdMapping()
Expand Down Expand Up @@ -58,6 +59,7 @@ export const AttachedOfferCard: React.FC<Props> = ({ offer, shouldFixHeight }) =
details={details}
rightTagLabel={distanceLabel}
accessibilityLabel={accessibilityLabel}
bottomBannerText={comingSoon}
LeftImageComponent={() => (
<OfferImage
imageUrl={attachedOffer?.thumbUrl}
Expand Down
5 changes: 5 additions & 0 deletions src/features/home/components/modules/HighlightOfferModule.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ const UnmemoizedHighlightOfferModule = (props: HighlightOfferModuleProps) => {
const categoryLabel = categoryLabelMapping[offer.subcategoryId]
const categoryId = categoryIdMapping[offer.subcategoryId]

const shouldDisplayPublicationDate = false
const publicationDate = new Date('2025-02-17T03:24:00')

return (
<Container>
<StyledTitleContainer>
Expand All @@ -105,6 +108,8 @@ const UnmemoizedHighlightOfferModule = (props: HighlightOfferModuleProps) => {
homeEntryId={homeEntryId}
backgroundImageUrl={props.image}
moduleId={props.id}
shouldDisplayPublicationDate={shouldDisplayPublicationDate}
publicationDate={publicationDate}
/>
) : (
<View>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,16 @@ describe('MarketingBlock', () => {

expect(screen.getByTestId('MarketingBlockContentDesktop')).toBeOnTheScreen()
})

it('should display a darkened backgroundImage when comingSoon is true', async () => {
render(<MarketingBlock {...props} comingSoon="Bientôt disponible" />)

expect(screen.getByTestId('black-gradient')).toBeOnTheScreen()
})

it('should not display a darkened backgroundImage when comingSoon is true', async () => {
render(<MarketingBlock {...props} />)

expect(screen.queryByTestId('black-gradient')).not.toBeOnTheScreen()
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export type MarketingBlockProps = {
accessibilityLabel?: string
backgroundImageUrl?: string
AttachedCardComponent: React.ReactNode
comingSoon?: string
}

export const MarketingBlock = (props: MarketingBlockProps) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import React from 'react'
import { PixelRatio } from 'react-native'
import styled from 'styled-components/native'

import { BlackGradient } from 'features/home/components/BlackGradient'
import { MarketingBlockProps } from 'features/home/components/modules/marketing/MarketingBlock'
import { FastImage } from 'libs/resizing-image-on-demand/FastImage'
import { InternalTouchableLink } from 'ui/components/touchableLink/InternalTouchableLink'
import { All } from 'ui/svg/icons/bicolor/All'
import { getSpacing } from 'ui/theme'
Expand All @@ -15,6 +15,7 @@ export const MarketingBlockContent = ({
AttachedCardComponent,
backgroundImageUrl,
accessibilityLabel,
comingSoon,
}: MarketingBlockProps) => {
return (
<InternalTouchableLink
Expand All @@ -23,9 +24,12 @@ export const MarketingBlockContent = ({
accessibilityLabel={accessibilityLabel}>
<BackgroundImageContainer>
{backgroundImageUrl ? (
<StyledFastImage url={backgroundImageUrl} />
<ImageBackground source={{ uri: backgroundImageUrl }}>
{comingSoon ? <BlackGradient height="100%" testID="black-gradient" /> : null}
</ImageBackground>
) : (
<ImagePlaceholder>
{comingSoon ? <BlackGradient height="100%" testID="black-gradient" /> : null}
<StyledAll />
</ImagePlaceholder>
)}
Expand All @@ -42,9 +46,10 @@ const BackgroundImageContainer = styled.View(({ theme }) => ({
overflow: 'hidden',
}))

const StyledFastImage = styled(FastImage)({
const ImageBackground = styled.ImageBackground({
height: '100%',
width: '100%',
overflow: 'hidden',
})

const ImagePlaceholder = styled.View({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import styled from 'styled-components/native'

import { BlackGradient } from 'features/home/components/BlackGradient'
import { MarketingBlockProps } from 'features/home/components/modules/marketing/MarketingBlock'
import { FastImage } from 'libs/resizing-image-on-demand/FastImage'
import { BlurAmount } from 'ui/components/BlurryWrapper/BlurAmount'
import { BlurryWrapper } from 'ui/components/BlurryWrapper/BlurryWrapper'
import { InternalTouchableLink } from 'ui/components/touchableLink/InternalTouchableLink'
Expand All @@ -17,15 +16,19 @@ export const MarketingBlockContentDesktop = ({
AttachedCardComponent,
backgroundImageUrl,
accessibilityLabel,
comingSoon,
}: MarketingBlockProps) => {
return (
<View testID="MarketingBlockContentDesktop">
<Container>
<BackgroundImageContainer>
{backgroundImageUrl ? (
<Image url={backgroundImageUrl} />
<SmallImageBackground source={{ uri: backgroundImageUrl }}>
{comingSoon ? <BlackGradient height="100%" testID="black-gradient" /> : null}
</SmallImageBackground>
) : (
<ImagePlaceholder>
{comingSoon ? <BlackGradient height="100%" testID="black-gradient" /> : null}
<StyledAll />
</ImagePlaceholder>
)}
Expand All @@ -39,11 +42,15 @@ export const MarketingBlockContentDesktop = ({
</Container>
<BackgroundContainer>
{backgroundImageUrl ? (
<ImageBackground source={{ uri: backgroundImageUrl }}>
<StyledBlurryWrapper blurAmount={BlurAmount.INTENSE}>
<BlackGradient height="100%" />
</StyledBlurryWrapper>
</ImageBackground>
<BigImageBackground source={{ uri: backgroundImageUrl }}>
{comingSoon ? (
<BlackGradient height="100%" testID="black-gradient">
<StyledBlurryWrapper blurAmount={BlurAmount.INTENSE} />
</BlackGradient>
) : (
<StyledBlurryWrapper blurAmount={BlurAmount.INTENSE} />
)}
</BigImageBackground>
) : (
<BackgroundImagePlaceholder>
<BlackGradient height="100%" />
Expand Down Expand Up @@ -73,23 +80,22 @@ const BackgroundImageContainer = styled.View(({ theme }) => ({
borderRadius: getSpacing(2),
}))

const Image = styled(FastImage)({
borderRadius: getSpacing(2),
flex: 1,
})

const ImagePlaceholder = styled.View({
alignItems: 'center',
justifyContent: 'center',
flex: 1,
})

const ImageBackground = styled.ImageBackground({
const BigImageBackground = styled.ImageBackground({
height: '100%',
width: '100%',
overflow: 'hidden',
})

const SmallImageBackground = styled(BigImageBackground)({
borderRadius: getSpacing(2),
})

const BackgroundImagePlaceholder = styled.View(({ theme }) => ({
backgroundColor: theme.colors.greyLight,
flex: 1,
Expand Down
Loading

0 comments on commit 5e56656

Please sign in to comment.