Skip to content

Commit

Permalink
(PC-33638) refactor(chronicle): renderItem in ChronicleCardListBase a…
Browse files Browse the repository at this point in the history
…s useCallback
  • Loading branch information
clesausse-pass committed Feb 3, 2025
1 parent 5f27be0 commit a9aa4f2
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 31 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import React, { createRef } from 'react'
import { FlatList } from 'react-native-gesture-handler'
import { ReactTestInstance } from 'react-test-renderer'

import { navigate } from '__mocks__/@react-navigation/native'
import { CHRONICLE_CARD_WIDTH } from 'features/chronicle/constant'
import { chroniclesSnap } from 'features/chronicle/fixtures/chroniclesSnap'
import { render, screen } from 'tests/utils'
import { render, screen, userEvent } from 'tests/utils'

import { ChronicleCardListBase } from './ChronicleCardListBase'

const user = userEvent.setup()

jest.useFakeTimers()

describe('ChronicleCardListBase', () => {
const ref = createRef<FlatList>()

Expand Down Expand Up @@ -34,4 +40,66 @@ describe('ChronicleCardListBase', () => {

expect(screen.getByText('La Nature Sauvage')).toBeOnTheScreen()
})

it('should display "Voir plus" button on all cards when shouldShowSeeMoreButton is true and offerId defined', () => {
render(
<ChronicleCardListBase
data={chroniclesSnap}
offset={CHRONICLE_CARD_WIDTH}
horizontal
ref={ref}
shouldShowSeeMoreButton
offerId={1}
/>
)

expect(screen.getAllByText('Voir plus')).toHaveLength(10)
})

it('should not display "Voir plus" button on all cards when shouldShowSeeMoreButton is not defined', () => {
render(
<ChronicleCardListBase
data={chroniclesSnap}
offset={CHRONICLE_CARD_WIDTH}
horizontal
ref={ref}
/>
)

expect(screen.queryByText('Voir plus')).not.toBeOnTheScreen()
})

it('should not display "Voir plus" button on all cards when offerId is not defined', () => {
render(
<ChronicleCardListBase
data={chroniclesSnap}
offset={CHRONICLE_CARD_WIDTH}
horizontal
ref={ref}
shouldShowSeeMoreButton
/>
)

expect(screen.queryByText('Voir plus')).not.toBeOnTheScreen()
})

it('should navigate to chronicles page with anchor on the selected chronicle when pressing "Voir plus" button', async () => {
render(
<ChronicleCardListBase
data={chroniclesSnap}
offset={CHRONICLE_CARD_WIDTH}
horizontal
ref={ref}
shouldShowSeeMoreButton
offerId={1}
/>
)

const seeMoreButtons = screen.getAllByText('Voir plus')

// Using as because links is never undefined and the typing is not correct
await user.press(seeMoreButtons[2] as ReactTestInstance)

expect(navigate).toHaveBeenNthCalledWith(1, 'Chronicles', { offerId: 1, chronicleId: 3 })
})
})
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import React, {
ReactElement,
forwardRef,
useCallback,
useEffect,
useImperativeHandle,
useMemo,
useRef,
} from 'react'
import { FlatList, FlatListProps, StyleProp, ViewStyle } from 'react-native'
import { FlatList, FlatListProps, StyleProp, View, ViewStyle } from 'react-native'
import styled from 'styled-components/native'

import { ChronicleCardData } from 'features/chronicle/type'
import { ButtonTertiaryBlack } from 'ui/components/buttons/ButtonTertiaryBlack'
import { styledButton } from 'ui/components/buttons/styledButton'
import { InternalTouchableLink } from 'ui/components/touchableLink/InternalTouchableLink'
import { PlainMore } from 'ui/svg/icons/PlainMore'
import { getSpacing } from 'ui/theme'

import { ChronicleCard } from '../ChronicleCard/ChronicleCard'
Expand Down Expand Up @@ -37,31 +42,6 @@ export type ChronicleCardListProps = Pick<
offerId?: number
}

const renderItem = ({
item,
cardWidth,
shouldShowSeeMoreButton,
offerId,
}: {
item: ChronicleCardData
cardWidth?: number
shouldShowSeeMoreButton?: boolean
offerId?: number
}) => {
return (
<ChronicleCard
id={item.id}
title={item.title}
subtitle={item.subtitle}
description={item.description}
date={item.date}
cardWidth={cardWidth}
navigateTo={{ screen: 'Chronicles', params: { offerId, chronicleId: item.id } }}
shouldShowSeeMoreButton={shouldShowSeeMoreButton}
/>
)
}

export const ChronicleCardListBase = forwardRef<
Partial<FlatList<ChronicleCardData>>,
ChronicleCardListProps
Expand Down Expand Up @@ -106,13 +86,38 @@ export const ChronicleCardListBase = forwardRef<
[separatorSize, horizontal]
)

const renderItem = useCallback(
({ item }: { item: ChronicleCardData }) => {
return (
<ChronicleCard
id={item.id}
title={item.title}
subtitle={item.subtitle}
description={item.description}
date={item.date}
cardWidth={cardWidth}>
{shouldShowSeeMoreButton && offerId ? (
<View>
<InternalTouchableLink
as={StyledButtonTertiaryBlack}
wording="Voir plus"
navigateTo={{ screen: 'Chronicles', params: { offerId, chronicleId: item.id } }}
/>
</View>
) : null}
</ChronicleCard>
)
},
[cardWidth, offerId, shouldShowSeeMoreButton]
)

return (
<FlatList
ref={listRef}
data={data}
style={style}
ListHeaderComponent={headerComponent}
renderItem={({ item }) => renderItem({ item, cardWidth, shouldShowSeeMoreButton, offerId })}
renderItem={renderItem}
keyExtractor={keyExtractor}
ItemSeparatorComponent={Separator}
contentContainerStyle={contentContainerStyle}
Expand All @@ -128,3 +133,13 @@ export const ChronicleCardListBase = forwardRef<
/>
)
})

const StyledPlainMore = styled(PlainMore).attrs(({ theme }) => ({
size: theme.icons.sizes.extraSmall,
}))``

const StyledButtonTertiaryBlack = styledButton(ButtonTertiaryBlack).attrs({
icon: StyledPlainMore,
iconPosition: 'right',
buttonHeight: 'extraSmall',
})``
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ describe('ChroniclesSection', () => {
data={chroniclesSnap}
subtitle="subtitle"
navigateTo={{ screen: 'Offer' }}
offerId={1}
/>
)

Expand All @@ -40,6 +41,7 @@ describe('ChroniclesSection', () => {
data={chroniclesSnap}
subtitle="subtitle"
navigateTo={{ screen: 'Offer' }}
offerId={1}
/>
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { ChronicleSectionProps } from './types'

export const ChronicleSection = (props: ChronicleSectionProps) => {
const { isDesktopViewport } = useTheme()
const { data, title, subtitle, ctaLabel, navigateTo, style } = props
const { data, title, subtitle, offerId, ctaLabel, navigateTo, style } = props

return isDesktopViewport ? (
<View style={style}>
Expand All @@ -35,7 +35,7 @@ export const ChronicleSection = (props: ChronicleSectionProps) => {
</Row>
{subtitle ? <StyledSubtitle>{subtitle}</StyledSubtitle> : null}
</Gutter>
<StyledChronicleCardlist data={data} />
<StyledChronicleCardlist data={data} offerId={offerId} shouldShowSeeMoreButton />
</View>
) : (
<ChronicleSectionBase {...props} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { ChronicleSectionProps } from './types'
export const ChronicleSectionBase = ({
data,
title,
offerId,
subtitle,
ctaLabel,
navigateTo,
Expand All @@ -25,7 +26,7 @@ export const ChronicleSectionBase = ({
<TypoDS.Title3 {...getHeadingAttrs(3)}>{title}</TypoDS.Title3>
{subtitle ? <StyledSubtitle>{subtitle}</StyledSubtitle> : null}
</Gutter>
<StyledChronicleCardlist data={data} />
<StyledChronicleCardlist data={data} shouldShowSeeMoreButton offerId={offerId} />
<Gutter>
<InternalTouchableLink
as={ButtonSecondaryBlack}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { InternalNavigationProps } from 'ui/components/touchableLink/types'
export type ChronicleSectionProps = {
data: ChronicleCardData[]
title: string
offerId: number
subtitle?: string
ctaLabel: string
navigateTo: InternalNavigationProps['navigateTo']
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ export const OfferContentBase: FunctionComponent<OfferContentBaseProps> = ({
title="L’avis du book club"
ctaLabel="Voir tous les avis"
subtitle="Des avis de jeunes passionnés sélectionnés par le pass Culture&nbsp;!"
offerId={offer.id}
data={chronicles}
navigateTo={{ screen: 'Chronicles', params: { offerId: offer.id } }}
/>
Expand Down

0 comments on commit a9aa4f2

Please sign in to comment.