From 85b6e7d2edee12b4e1daef65bbc490468bdad9c4 Mon Sep 17 00:00:00 2001 From: Bruno Peyrou Date: Fri, 27 Dec 2024 16:33:40 +0000 Subject: [PATCH] (PC-33463) refactor(Venue): refacto Venue page --- .../Venue/Venue.native.test.tsx.native-snap | 11188 ++++++++-------- .../VenueBody/VenueBody.native.test.tsx | 29 - .../venue/components/VenueBody/VenueBody.tsx | 57 +- .../VenueCTA/VenueCTA.native.test.tsx | 40 +- .../venue/components/VenueCTA/VenueCTA.tsx | 12 +- .../VenueContent/VenueContent.native.test.tsx | 122 +- .../components/VenueContent/VenueContent.tsx | 85 +- .../VenueContent/VenueHeaderWrapper.tsx | 16 + .../VenueContent/VenueHeaderWrapper.web.tsx | 16 + .../VenueMessagingApps/VenueMessagingApps.tsx | 19 +- .../VenueThematicSection.tsx | 2 +- .../VenueTopComponentBase.tsx | 67 +- .../venue/components/VenueWebMetaHeader.tsx | 12 +- .../venue/pages/Venue/Venue.native.test.tsx | 108 +- src/features/venue/pages/Venue/Venue.tsx | 53 +- src/features/venue/types.ts | 9 + 16 files changed, 5926 insertions(+), 5909 deletions(-) create mode 100644 src/features/venue/components/VenueContent/VenueHeaderWrapper.tsx create mode 100644 src/features/venue/components/VenueContent/VenueHeaderWrapper.web.tsx diff --git a/__snapshots__/features/venue/pages/Venue/Venue.native.test.tsx.native-snap b/__snapshots__/features/venue/pages/Venue/Venue.native.test.tsx.native-snap index b74854f4915..959312a468d 100644 --- a/__snapshots__/features/venue/pages/Venue/Venue.native.test.tsx.native-snap +++ b/__snapshots__/features/venue/pages/Venue/Venue.native.test.tsx.native-snap @@ -103,97 +103,44 @@ exports[` should match snapshot 1`] = ` } > - - Librairie - - - - - - - Le Petit Rintintin 1 - - - should match snapshot 1`] = ` "color": "#161617", "fontFamily": "Montserrat-SemiBold", "fontSize": 12, - "lineHeight": 19.2, - }, - ] - } - > - Adresse - - - 1 boulevard Poissonnière, 75000 Paris + Librairie - + + + > + Le Petit Rintintin 1 + - - + - - - button-icon-left-SVG-Mock - - - - + Adresse + - Copier l’adresse + 1 boulevard Poissonnière, 75000 Paris - - + should match snapshot 1`] = ` { "alignItems": "center", "backgroundColor": "transparent", - "borderRadius": 0, - "borderWidth": 0, + "borderRadius": 24, "flexDirection": "row", - "justifyContent": "center", - "marginTop": 0, + "justifyContent": "flex-start", "maxWidth": 500, - "minHeight": 20, + "minHeight": 40, "opacity": 1, - "paddingBottom": 0, - "paddingLeft": 0, - "paddingRight": 0, - "paddingTop": 0, + "paddingBottom": 2, + "paddingLeft": 2, + "paddingRight": 2, + "paddingTop": 2, "userSelect": "auto", - "width": "auto", + "width": "100%", } } - testID="Voir l’itinéraire" + testID="Copier l’adresse" > should match snapshot 1`] = ` } > should match snapshot 1`] = ` ] } > - Voir l’itinéraire + Copier l’adresse + + + + + + + button-icon-left-SVG-Mock + + + + + + Voir l’itinéraire + + + + - - + } + > - + /> + - - - Offres disponibles - - - - - - - - Infos pratiques - + + Offres disponibles + + + + - - - - - - - - + "flexBasis": 0, + "flexGrow": 1, + "flexShrink": 1, + "maxWidth": 180, + "opacity": 1, + "userSelect": "auto", + } + } + > - Toutes les offres + Infos pratiques - - + + + + + + + - - + + + Toutes les offres + + + + + + should match snapshot 1`] = ` }, "venue": {}, }, - ], - "_firstIndexToProcess": 0, - "_hasStableIds": true, - "_requiresDataChangeHandling": false, - "_size": 3, - "getStableId": [Function], - "rowHasChanged": [Function], + ] } - } - disableRecycling={false} - estimatedItemSize={144} - extendedState={{}} - externalScrollView={[Function]} - finalRenderAheadOffset={187.5} - forceNonDeterministicRendering={true} - horizontal={true} - initialOffset={0} - initialRenderIndex={0} - isHorizontal={true} - keyExtractor={[Function]} - layoutProvider={ - GridLayoutProviderWithProps { - "_acceptableRelayoutDelta": 1, - "_getHeightOrWidth": [Function], - "_getLayoutTypeForIndex": [Function], - "_getSpan": [Function], - "_hasExpired": false, - "_isHorizontal": true, - "_lastLayoutManager": GridLayoutManager { - "_acceptableRelayoutDelta": 1, - "_getSpan": [Function], - "_isGridHorizontal": true, - "_isHorizontal": true, - "_layoutProvider": [Circular], - "_layouts": [ + dataProvider={ + DataProvider { + "_data": [ { - "height": 250, - "type": 0, - "width": 144, - "x": 0, - "y": 0, + "_geoloc": { + "lat": 47.8898, + "lng": -2.83593, + }, + "objectID": "223342", + "offer": { + "dates": [ + 1629312300, + 1629485100, + 1629657900, + ], + "isDigital": false, + "isDuo": true, + "name": "Titane - VF", + "prices": [ + 0, + 0, + 0, + ], + "subcategoryId": "CINE_PLEIN_AIR", + "thumbUrl": "https://storage.googleapis.com/passculture-metier-ehp-testing-assets/thumbs/products/FARMG", + }, + "venue": {}, }, { - "height": 250, - "type": 0, - "width": 144, - "x": 144, - "y": 0, + "_geoloc": { + "lat": 47.8898, + "lng": -2.83593, + }, + "objectID": "223338", + "offer": { + "dates": [ + 1629312300, + 1629485100, + 1629657900, + ], + "isDigital": false, + "isDuo": true, + "name": "Bac Nord - VF", + "prices": [ + 0, + 0, + 0, + ], + "subcategoryId": "CINE_PLEIN_AIR", + "thumbUrl": "https://storage.googleapis.com/passculture-metier-ehp-testing-assets/thumbs/products/FARMG", + }, + "venue": {}, }, - { - "height": 250, - "type": 0, - "width": 144, - "x": 288, - "y": 0, - }, - ], - "_maxSpan": 1, - "_renderWindowSize": { - "height": 250, - "width": 800, - }, - "_totalHeight": 250, - "_totalWidth": 432, - "_window": { - "height": 250, - "width": 800, - }, - }, - "_maxSpan": 1, - "_renderWindowSize": { - "height": 250, - "width": 800, - }, - "_setLayoutForType": [Function], - "_tempDim": { - "height": 0, - "width": 0, - }, - "averageWindow": AverageWindow { - "currentAverage": 144, - "currentCount": 1, - "inputValues": [ - 144, - , - , - , - , - , - , - , - , - , - , - , - ], - "nextIndex": 1, - }, - "defaultEstimatedItemSize": 100, - "layoutObject": { - "size": undefined, - "span": undefined, - }, - "props": { - "ItemSeparatorComponent": { - "$$typeof": Symbol(react.forward_ref), - "attrs": [ - { - "width": 16, - }, - ], - "inlineStyle": InlineStyle { - "rules": [ - [Function], - "", - ], - }, - "render": [Function], - "shouldForwardProp": undefined, - "styledComponentId": "StyledNativeComponent", - "target": [Function], - "withComponent": [Function], - }, - "ListFooterComponent": { - "$$typeof": Symbol(react.forward_ref), - "attrs": [ - { - "width": 24, - }, - ], - "inlineStyle": InlineStyle { - "rules": [ - [Function], - "", - ], - }, - "render": [Function], - "shouldForwardProp": undefined, - "styledComponentId": "StyledNativeComponent", - "target": [Function], - "withComponent": [Function], - }, - "ListHeaderComponent": { - "$$typeof": Symbol(react.forward_ref), - "attrs": [ - { - "width": 24, - }, - ], - "inlineStyle": InlineStyle { - "rules": [ - [Function], - "", - ], - }, - "render": [Function], - "shouldForwardProp": undefined, - "styledComponentId": "StyledNativeComponent", - "target": [Function], - "withComponent": [Function], - }, - "data": [ { "_geoloc": { "lat": 47.8898, "lng": -2.83593, }, - "objectID": "223342", + "objectID": "223339", "offer": { "dates": [ 1629312300, @@ -1258,1217 +1072,1405 @@ exports[` should match snapshot 1`] = ` ], "isDigital": false, "isDuo": true, - "name": "Titane - VF", + "name": "Black Widow - VF", "prices": [ 0, 0, 0, ], "subcategoryId": "CINE_PLEIN_AIR", - "thumbUrl": "https://storage.googleapis.com/passculture-metier-ehp-testing-assets/thumbs/products/FARMG", + "thumbUrl": "https://storage.googleapis.com/passculture-metier-ehp-testing-assets/thumbs/products/FARMA", }, "venue": {}, }, - { - "_geoloc": { - "lat": 47.8898, - "lng": -2.83593, + ], + "_firstIndexToProcess": 0, + "_hasStableIds": true, + "_requiresDataChangeHandling": false, + "_size": 3, + "getStableId": [Function], + "rowHasChanged": [Function], + } + } + disableRecycling={false} + estimatedItemSize={144} + extendedState={{}} + externalScrollView={[Function]} + finalRenderAheadOffset={187.5} + forceNonDeterministicRendering={true} + horizontal={true} + initialOffset={0} + initialRenderIndex={0} + isHorizontal={true} + keyExtractor={[Function]} + layoutProvider={ + GridLayoutProviderWithProps { + "_acceptableRelayoutDelta": 1, + "_getHeightOrWidth": [Function], + "_getLayoutTypeForIndex": [Function], + "_getSpan": [Function], + "_hasExpired": false, + "_isHorizontal": true, + "_lastLayoutManager": GridLayoutManager { + "_acceptableRelayoutDelta": 1, + "_getSpan": [Function], + "_isGridHorizontal": true, + "_isHorizontal": true, + "_layoutProvider": [Circular], + "_layouts": [ + { + "height": 250, + "type": 0, + "width": 144, + "x": 0, + "y": 0, }, - "objectID": "223338", - "offer": { - "dates": [ - 1629312300, - 1629485100, - 1629657900, - ], - "isDigital": false, - "isDuo": true, - "name": "Bac Nord - VF", - "prices": [ - 0, - 0, - 0, - ], - "subcategoryId": "CINE_PLEIN_AIR", - "thumbUrl": "https://storage.googleapis.com/passculture-metier-ehp-testing-assets/thumbs/products/FARMG", + { + "height": 250, + "type": 0, + "width": 144, + "x": 144, + "y": 0, }, - "venue": {}, + { + "height": 250, + "type": 0, + "width": 144, + "x": 288, + "y": 0, + }, + ], + "_maxSpan": 1, + "_renderWindowSize": { + "height": 250, + "width": 800, }, - { - "_geoloc": { - "lat": 47.8898, - "lng": -2.83593, + "_totalHeight": 250, + "_totalWidth": 432, + "_window": { + "height": 250, + "width": 800, + }, + }, + "_maxSpan": 1, + "_renderWindowSize": { + "height": 250, + "width": 800, + }, + "_setLayoutForType": [Function], + "_tempDim": { + "height": 0, + "width": 0, + }, + "averageWindow": AverageWindow { + "currentAverage": 144, + "currentCount": 1, + "inputValues": [ + 144, + , + , + , + , + , + , + , + , + , + , + , + ], + "nextIndex": 1, + }, + "defaultEstimatedItemSize": 100, + "layoutObject": { + "size": undefined, + "span": undefined, + }, + "props": { + "ItemSeparatorComponent": { + "$$typeof": Symbol(react.forward_ref), + "attrs": [ + { + "width": 16, + }, + ], + "inlineStyle": InlineStyle { + "rules": [ + [Function], + "", + ], }, - "objectID": "223339", - "offer": { - "dates": [ - 1629312300, - 1629485100, - 1629657900, + "render": [Function], + "shouldForwardProp": undefined, + "styledComponentId": "StyledNativeComponent", + "target": [Function], + "withComponent": [Function], + }, + "ListFooterComponent": { + "$$typeof": Symbol(react.forward_ref), + "attrs": [ + { + "width": 24, + }, + ], + "inlineStyle": InlineStyle { + "rules": [ + [Function], + "", ], - "isDigital": false, - "isDuo": true, - "name": "Black Widow - VF", - "prices": [ - 0, - 0, - 0, + }, + "render": [Function], + "shouldForwardProp": undefined, + "styledComponentId": "StyledNativeComponent", + "target": [Function], + "withComponent": [Function], + }, + "ListHeaderComponent": { + "$$typeof": Symbol(react.forward_ref), + "attrs": [ + { + "width": 24, + }, + ], + "inlineStyle": InlineStyle { + "rules": [ + [Function], + "", ], - "subcategoryId": "CINE_PLEIN_AIR", - "thumbUrl": "https://storage.googleapis.com/passculture-metier-ehp-testing-assets/thumbs/products/FARMA", }, - "venue": {}, + "render": [Function], + "shouldForwardProp": undefined, + "styledComponentId": "StyledNativeComponent", + "target": [Function], + "withComponent": [Function], }, - ], - "drawDistance": 187.5, - "estimatedItemSize": 144, - "horizontal": true, - "keyExtractor": [Function], - "numColumns": 1, - "onContentSizeChange": [Function], - "onEndReached": undefined, - "onEndReachedThreshold": 0.2, - "onScroll": [Function], - "renderItem": [Function], - "scrollEnabled": true, - "scrollEventThrottle": 16, - "showsHorizontalScrollIndicator": false, - "testID": "offersModuleList", - }, - "renderWindowInsets": { - "height": 0, - "width": 0, - }, - "shouldRefreshWithAnchoring": true, - } - } - maxRenderAhead={562.5} - numColumns={1} - onContentSizeChange={[Function]} - onEndReached={[Function]} - onEndReachedThreshold={0} - onEndReachedThresholdRelative={0.2} - onItemLayout={[Function]} - onLayout={[Function]} - onScroll={[Function]} - onScrollBeginDrag={[Function]} - onSizeChanged={[Function]} - onVisibleIndicesChanged={[Function]} - removeClippedSubviews={false} - renderAheadOffset={0} - renderAheadStep={187.5} - renderContentContainer={[Function]} - renderItem={[Function]} - renderItemContainer={[Function]} - rowRenderer={[Function]} - scrollEnabled={true} - scrollEventThrottle={16} - scrollThrottle={16} - scrollViewProps={ - { - "contentContainerStyle": { - "backgroundColor": undefined, - "minHeight": 1, - "minWidth": 1, - "paddingBottom": 0, - "paddingTop": 0, - }, - "onLayout": [Function], - "onScrollBeginDrag": [Function], - "refreshControl": undefined, - "style": { - "minHeight": 1, - "minWidth": 1, - }, + "data": [ + { + "_geoloc": { + "lat": 47.8898, + "lng": -2.83593, + }, + "objectID": "223342", + "offer": { + "dates": [ + 1629312300, + 1629485100, + 1629657900, + ], + "isDigital": false, + "isDuo": true, + "name": "Titane - VF", + "prices": [ + 0, + 0, + 0, + ], + "subcategoryId": "CINE_PLEIN_AIR", + "thumbUrl": "https://storage.googleapis.com/passculture-metier-ehp-testing-assets/thumbs/products/FARMG", + }, + "venue": {}, + }, + { + "_geoloc": { + "lat": 47.8898, + "lng": -2.83593, + }, + "objectID": "223338", + "offer": { + "dates": [ + 1629312300, + 1629485100, + 1629657900, + ], + "isDigital": false, + "isDuo": true, + "name": "Bac Nord - VF", + "prices": [ + 0, + 0, + 0, + ], + "subcategoryId": "CINE_PLEIN_AIR", + "thumbUrl": "https://storage.googleapis.com/passculture-metier-ehp-testing-assets/thumbs/products/FARMG", + }, + "venue": {}, + }, + { + "_geoloc": { + "lat": 47.8898, + "lng": -2.83593, + }, + "objectID": "223339", + "offer": { + "dates": [ + 1629312300, + 1629485100, + 1629657900, + ], + "isDigital": false, + "isDuo": true, + "name": "Black Widow - VF", + "prices": [ + 0, + 0, + 0, + ], + "subcategoryId": "CINE_PLEIN_AIR", + "thumbUrl": "https://storage.googleapis.com/passculture-metier-ehp-testing-assets/thumbs/products/FARMA", + }, + "venue": {}, + }, + ], + "drawDistance": 187.5, + "estimatedItemSize": 144, + "horizontal": true, + "keyExtractor": [Function], + "numColumns": 1, + "onContentSizeChange": [Function], + "onEndReached": undefined, + "onEndReachedThreshold": 0.2, + "onScroll": [Function], + "renderItem": [Function], + "scrollEnabled": true, + "scrollEventThrottle": 16, + "showsHorizontalScrollIndicator": false, + "testID": "offersModuleList", + }, + "renderWindowInsets": { + "height": 0, + "width": 0, + }, + "shouldRefreshWithAnchoring": true, + } } - } - showsHorizontalScrollIndicator={false} - style={ - { - "minHeight": 1, - "minWidth": 1, + maxRenderAhead={562.5} + numColumns={1} + onContentSizeChange={[Function]} + onEndReached={[Function]} + onEndReachedThreshold={0} + onEndReachedThresholdRelative={0.2} + onItemLayout={[Function]} + onLayout={[Function]} + onScroll={[Function]} + onScrollBeginDrag={[Function]} + onSizeChanged={[Function]} + onVisibleIndicesChanged={[Function]} + removeClippedSubviews={false} + renderAheadOffset={0} + renderAheadStep={187.5} + renderContentContainer={[Function]} + renderItem={[Function]} + renderItemContainer={[Function]} + rowRenderer={[Function]} + scrollEnabled={true} + scrollEventThrottle={16} + scrollThrottle={16} + scrollViewProps={ + { + "contentContainerStyle": { + "backgroundColor": undefined, + "minHeight": 1, + "minWidth": 1, + "paddingBottom": 0, + "paddingTop": 0, + }, + "onLayout": [Function], + "onScrollBeginDrag": [Function], + "refreshControl": undefined, + "style": { + "minHeight": 1, + "minWidth": 1, + }, + } } - } - suppressBoundedSizeException={true} - testID="offersModuleList" - windowCorrectionConfig={ - { - "applyToInitialOffset": true, - "applyToItemScroll": true, - "value": { - "endCorrection": 0, - "startCorrection": 0, - "windowShift": -1, - }, + showsHorizontalScrollIndicator={false} + style={ + { + "minHeight": 1, + "minWidth": 1, + } } - } - > - - + } + > + - - - - + + + - - - + } + > + - - Bac Nord - VF - - - Dès le 18 août 2021 - - - Gratuit - - - - + Bac Nord - VF + + - + Dès le 18 août 2021 + + + testID="priceIsDuo" + > + Gratuit + - + + + + - - Cinéma - + + Cinéma + + - - - - - + + - - + + - - - Black Widow - VF - - - Dès le 18 août 2021 - - - Gratuit - - - - + Black Widow - VF + + - + Dès le 18 août 2021 + + + testID="priceIsDuo" + > + Gratuit + - + + + + - - Cinéma - + + Cinéma + + - - - - + - - + } + > + - - Titane - VF - - - Dès le 18 août 2021 - - - Gratuit - - - - + Titane - VF + + - + Dès le 18 août 2021 + + + testID="priceIsDuo" + > + Gratuit + - + + + + - - Cinéma - + + Cinéma + + - - + + + + - - - - - - - + } + > + - - Bac Nord - VF - - - Dès le 18 août 2021 - - - Gratuit - - - - + Bac Nord - VF + + - + Dès le 18 août 2021 + + + testID="priceIsDuo" + > + Gratuit + - + + + + - - Cinéma - + + Cinéma + + @@ -2477,191 +2479,170 @@ exports[` should match snapshot 1`] = ` - - + + - - - - - - - Test - - - + - - + + + Test + + + + + + should match snapshot 1`] = ` "city": "Jest", }, }, - ], - "_firstIndexToProcess": 0, - "_hasStableIds": true, - "_requiresDataChangeHandling": false, - "_size": 1, - "getStableId": [Function], - "rowHasChanged": [Function], + ] } - } - disableRecycling={false} - estimatedItemSize={192} - extendedState={{}} - externalScrollView={[Function]} - finalRenderAheadOffset={187.5} - forceNonDeterministicRendering={true} - horizontal={true} - initialOffset={0} - initialRenderIndex={0} - isHorizontal={true} - keyExtractor={[Function]} - layoutProvider={ - GridLayoutProviderWithProps { - "_acceptableRelayoutDelta": 1, - "_getHeightOrWidth": [Function], - "_getLayoutTypeForIndex": [Function], - "_getSpan": [Function], - "_hasExpired": false, - "_isHorizontal": true, - "_lastLayoutManager": GridLayoutManager { + dataProvider={ + DataProvider { + "_data": [ + { + "_geoloc": { + "lat": 2, + "lng": 2, + }, + "objectID": "12", + "offer": { + "name": "Test", + "subcategoryId": "ABO_BIBLIOTHEQUE", + }, + "venue": { + "address": "Avenue des Tests", + "city": "Jest", + }, + }, + ], + "_firstIndexToProcess": 0, + "_hasStableIds": true, + "_requiresDataChangeHandling": false, + "_size": 1, + "getStableId": [Function], + "rowHasChanged": [Function], + } + } + disableRecycling={false} + estimatedItemSize={192} + extendedState={{}} + externalScrollView={[Function]} + finalRenderAheadOffset={187.5} + forceNonDeterministicRendering={true} + horizontal={true} + initialOffset={0} + initialRenderIndex={0} + isHorizontal={true} + keyExtractor={[Function]} + layoutProvider={ + GridLayoutProviderWithProps { "_acceptableRelayoutDelta": 1, + "_getHeightOrWidth": [Function], + "_getLayoutTypeForIndex": [Function], "_getSpan": [Function], - "_isGridHorizontal": true, + "_hasExpired": false, "_isHorizontal": true, - "_layoutProvider": [Circular], - "_layouts": [ - { + "_lastLayoutManager": GridLayoutManager { + "_acceptableRelayoutDelta": 1, + "_getSpan": [Function], + "_isGridHorizontal": true, + "_isHorizontal": true, + "_layoutProvider": [Circular], + "_layouts": [ + { + "height": 250, + "type": 0, + "width": 192, + "x": 0, + "y": 0, + }, + ], + "_maxSpan": 1, + "_renderWindowSize": { "height": 250, - "type": 0, - "width": 192, - "x": 0, - "y": 0, + "width": 800, }, - ], + "_totalHeight": 250, + "_totalWidth": 192, + "_window": { + "height": 250, + "width": 800, + }, + }, "_maxSpan": 1, "_renderWindowSize": { "height": 250, "width": 800, }, - "_totalHeight": 250, - "_totalWidth": 192, - "_window": { - "height": 250, - "width": 800, + "_setLayoutForType": [Function], + "_tempDim": { + "height": 0, + "width": 0, }, - }, - "_maxSpan": 1, - "_renderWindowSize": { - "height": 250, - "width": 800, - }, - "_setLayoutForType": [Function], - "_tempDim": { - "height": 0, - "width": 0, - }, - "averageWindow": AverageWindow { - "currentAverage": 192, - "currentCount": 1, - "inputValues": [ - 192, - , - , - , - , - , - , - , - ], - "nextIndex": 1, - }, - "defaultEstimatedItemSize": 100, - "layoutObject": { - "size": undefined, - "span": undefined, - }, - "props": { - "ItemSeparatorComponent": { - "$$typeof": Symbol(react.forward_ref), - "attrs": [ - { - "width": 16, - }, + "averageWindow": AverageWindow { + "currentAverage": 192, + "currentCount": 1, + "inputValues": [ + 192, + , + , + , + , + , + , + , ], - "inlineStyle": InlineStyle { - "rules": [ - [Function], - "", + "nextIndex": 1, + }, + "defaultEstimatedItemSize": 100, + "layoutObject": { + "size": undefined, + "span": undefined, + }, + "props": { + "ItemSeparatorComponent": { + "$$typeof": Symbol(react.forward_ref), + "attrs": [ + { + "width": 16, + }, ], + "inlineStyle": InlineStyle { + "rules": [ + [Function], + "", + ], + }, + "render": [Function], + "shouldForwardProp": undefined, + "styledComponentId": "StyledNativeComponent", + "target": [Function], + "withComponent": [Function], }, - "render": [Function], - "shouldForwardProp": undefined, - "styledComponentId": "StyledNativeComponent", - "target": [Function], - "withComponent": [Function], - }, - "ListFooterComponent": { - "$$typeof": Symbol(react.forward_ref), - "attrs": [ - { - "width": 24, + "ListFooterComponent": { + "$$typeof": Symbol(react.forward_ref), + "attrs": [ + { + "width": 24, + }, + ], + "inlineStyle": InlineStyle { + "rules": [ + [Function], + "", + ], }, - ], - "inlineStyle": InlineStyle { - "rules": [ - [Function], - "", + "render": [Function], + "shouldForwardProp": undefined, + "styledComponentId": "StyledNativeComponent", + "target": [Function], + "withComponent": [Function], + }, + "ListHeaderComponent": { + "$$typeof": Symbol(react.forward_ref), + "attrs": [ + { + "width": 24, + }, ], + "inlineStyle": InlineStyle { + "rules": [ + [Function], + "", + ], + }, + "render": [Function], + "shouldForwardProp": undefined, + "styledComponentId": "StyledNativeComponent", + "target": [Function], + "withComponent": [Function], }, - "render": [Function], - "shouldForwardProp": undefined, - "styledComponentId": "StyledNativeComponent", - "target": [Function], - "withComponent": [Function], - }, - "ListHeaderComponent": { - "$$typeof": Symbol(react.forward_ref), - "attrs": [ + "data": [ { - "width": 24, + "_geoloc": { + "lat": 2, + "lng": 2, + }, + "objectID": "12", + "offer": { + "name": "Test", + "subcategoryId": "ABO_BIBLIOTHEQUE", + }, + "venue": { + "address": "Avenue des Tests", + "city": "Jest", + }, }, ], - "inlineStyle": InlineStyle { - "rules": [ - [Function], - "", - ], - }, - "render": [Function], - "shouldForwardProp": undefined, - "styledComponentId": "StyledNativeComponent", - "target": [Function], - "withComponent": [Function], + "drawDistance": 187.5, + "estimatedItemSize": 192, + "horizontal": true, + "keyExtractor": [Function], + "numColumns": 1, + "onContentSizeChange": [Function], + "onEndReached": [Function], + "onEndReachedThreshold": 0.2, + "onScroll": [Function], + "renderItem": [Function], + "scrollEnabled": true, + "scrollEventThrottle": 16, + "showsHorizontalScrollIndicator": false, + "testID": "offersModuleList", }, - "data": [ - { - "_geoloc": { - "lat": 2, - "lng": 2, - }, - "objectID": "12", - "offer": { - "name": "Test", - "subcategoryId": "ABO_BIBLIOTHEQUE", - }, - "venue": { - "address": "Avenue des Tests", - "city": "Jest", - }, - }, - ], - "drawDistance": 187.5, - "estimatedItemSize": 192, - "horizontal": true, - "keyExtractor": [Function], - "numColumns": 1, - "onContentSizeChange": [Function], - "onEndReached": [Function], - "onEndReachedThreshold": 0.2, - "onScroll": [Function], - "renderItem": [Function], - "scrollEnabled": true, - "scrollEventThrottle": 16, - "showsHorizontalScrollIndicator": false, - "testID": "offersModuleList", - }, - "renderWindowInsets": { - "height": 0, - "width": 0, - }, - "shouldRefreshWithAnchoring": true, + "renderWindowInsets": { + "height": 0, + "width": 0, + }, + "shouldRefreshWithAnchoring": true, + } } - } - maxRenderAhead={562.5} - numColumns={1} - onContentSizeChange={[Function]} - onEndReached={[Function]} - onEndReachedThreshold={0} - onEndReachedThresholdRelative={0.2} - onItemLayout={[Function]} - onLayout={[Function]} - onScroll={[Function]} - onScrollBeginDrag={[Function]} - onSizeChanged={[Function]} - onVisibleIndicesChanged={[Function]} - removeClippedSubviews={false} - renderAheadOffset={0} - renderAheadStep={187.5} - renderContentContainer={[Function]} - renderItem={[Function]} - renderItemContainer={[Function]} - rowRenderer={[Function]} - scrollEnabled={true} - scrollEventThrottle={16} - scrollThrottle={16} - scrollViewProps={ - { - "contentContainerStyle": { - "backgroundColor": undefined, - "minHeight": 1, - "minWidth": 1, - "paddingBottom": 0, - "paddingTop": 0, - }, - "onLayout": [Function], - "onScrollBeginDrag": [Function], - "refreshControl": undefined, - "style": { + maxRenderAhead={562.5} + numColumns={1} + onContentSizeChange={[Function]} + onEndReached={[Function]} + onEndReachedThreshold={0} + onEndReachedThresholdRelative={0.2} + onItemLayout={[Function]} + onLayout={[Function]} + onScroll={[Function]} + onScrollBeginDrag={[Function]} + onSizeChanged={[Function]} + onVisibleIndicesChanged={[Function]} + removeClippedSubviews={false} + renderAheadOffset={0} + renderAheadStep={187.5} + renderContentContainer={[Function]} + renderItem={[Function]} + renderItemContainer={[Function]} + rowRenderer={[Function]} + scrollEnabled={true} + scrollEventThrottle={16} + scrollThrottle={16} + scrollViewProps={ + { + "contentContainerStyle": { + "backgroundColor": undefined, + "minHeight": 1, + "minWidth": 1, + "paddingBottom": 0, + "paddingTop": 0, + }, + "onLayout": [Function], + "onScrollBeginDrag": [Function], + "refreshControl": undefined, + "style": { + "minHeight": 1, + "minWidth": 1, + }, + } + } + showsHorizontalScrollIndicator={false} + style={ + { "minHeight": 1, "minWidth": 1, - }, - } - } - showsHorizontalScrollIndicator={false} - style={ - { - "minHeight": 1, - "minWidth": 1, - } - } - suppressBoundedSizeException={true} - testID="offersModuleList" - windowCorrectionConfig={ - { - "applyToInitialOffset": true, - "applyToItemScroll": true, - "value": { - "endCorrection": 0, - "startCorrection": 0, - "windowShift": -1, - }, + } } - } - > - - + } + > + - - - - - + + + + + - - + } + > + - - Test - - - - - + Test + + + + + - - - categoryIcon-SVG-Mock - - - - - + + + categoryIcon-SVG-Mock + + + + - - Livre - + + Livre + + - - - - - + + - - - - + > + width={24} + /> + + + + - - Test - - - - - + Test + + + + + - - - categoryIcon-SVG-Mock - - - - - + + + categoryIcon-SVG-Mock + + + + - - Livre - - - - - - - - - - - - - - - - - - - - - - - - - - - - undefined-SVG-Mock - - - - - - - - Fan de lecture ? - - - Reçois nos recos lecture, nos jeux-concours et le meilleur de l’actu littéraire ! - - - - - undefined-Lottie-Mock - - - - Suivre le thème - + + Livre + + + + + + + + + + + + + + + - - - - - - + - - Passe le bon plan ! - + + + + + undefined-SVG-Mock + + + + + + + Fan de lecture ? + + + Reçois nos recos lecture, nos jeux-concours et le meilleur de l’actu littéraire ! + + + + undefined-Lottie-Mock + - + - - - - - undefined-SVG-Mock - - - - - - Envoyer sur -Instagram - - - - + "color": "#161617", + "fontFamily": "Montserrat-SemiBold", + "fontSize": 12, + "lineHeight": 19.2, + }, + ] + } + > + Suivre le thème + + + + + + + + + + + + + + + Passe le bon plan ! + - - undefined-SVG-Mock + + + + undefined-SVG-Mock + + + + + + Envoyer sur +Instagram - - - Envoyer sur -WhatsApp - - - - - - - - undefined-SVG-Mock - - - - - - Envoyer sur -iMessage - + + + + + undefined-SVG-Mock + + + + + + Envoyer sur +WhatsApp + + + - - - - - - undefined-SVG-Mock - + + + undefined-SVG-Mock + + + + + Envoyer sur +iMessage + + + - - Plus + + + + + + undefined-SVG-Mock + + + + + + + Plus d’options - + + + + + + - - - - @@ -5059,97 +5050,44 @@ exports[` should match snapshot with practical information 1`] = ` } > - - Librairie - - - - - - - Le Petit Rintintin 1 - - - should match snapshot with practical information 1`] = ` "color": "#161617", "fontFamily": "Montserrat-SemiBold", "fontSize": 12, - "lineHeight": 19.2, - }, - ] - } - > - Adresse - - - 1 boulevard Poissonnière, 75000 Paris + Librairie - + + + > + Le Petit Rintintin 1 + - - + - - - button-icon-left-SVG-Mock - - - - + Adresse + - Copier l’adresse + 1 boulevard Poissonnière, 75000 Paris - - + should match snapshot with practical information 1`] = ` { "alignItems": "center", "backgroundColor": "transparent", - "borderRadius": 0, - "borderWidth": 0, + "borderRadius": 24, "flexDirection": "row", - "justifyContent": "center", - "marginTop": 0, + "justifyContent": "flex-start", "maxWidth": 500, - "minHeight": 20, + "minHeight": 40, "opacity": 1, - "paddingBottom": 0, - "paddingLeft": 0, - "paddingRight": 0, - "paddingTop": 0, + "paddingBottom": 2, + "paddingLeft": 2, + "paddingRight": 2, + "paddingTop": 2, "userSelect": "auto", - "width": "auto", + "width": "100%", } } - testID="Voir l’itinéraire" + testID="Copier l’adresse" > should match snapshot with practical information 1`] = ` } > should match snapshot with practical information 1`] = ` numberOfLines={1} style={ [ - { - "color": "#161617", - "fontFamily": "Montserrat-Bold", - "fontSize": 15, - "lineHeight": 20, - "maxWidth": "100%", - }, - ] - } - > - Voir l’itinéraire - - - - - - - - - - - - - - - - - - - - Offres disponibles - - - - - - + { + "color": "#161617", + "fontFamily": "Montserrat-Bold", + "fontSize": 15, + "lineHeight": 20, + "maxWidth": "100%", + }, + ] + } + > + Copier l’adresse + + + - - Infos pratiques - + + + + + button-icon-left-SVG-Mock + + + + + + Voir l’itinéraire + + + - - - + + + + + + + - - - - Modalités de retrait - - - - How to withdraw, https://test.com - - - - - - Description - - - + - https://pass.culture.fr/ lorem ipsum consectetur adipisicing elit. Debitis officiis maiores quia unde, hic quisquam odit ea quo ipsam possimus, labore nesciunt numquam. Id itaque in sed sapiente blanditiis necessitatibus. consectetur adipisicing elit. Debitis officiis maiores quia unde, hic quisquam odit ea quo ipsam possimus, consectetur adipisicing elit. Debitis officiis maiores quia unde, hic quisquam odit ea quo ipsam possimus, - + /> + > + + + Offres disponibles + + + + + - + + + Infos pratiques + + + + + + - Contact - + /> + + - + + + + Modalités de retrait + + + + How to withdraw, https://test.com + + + + + + > + Description + + + https://pass.culture.fr/ lorem ipsum consectetur adipisicing elit. Debitis officiis maiores quia unde, hic quisquam odit ea quo ipsam possimus, labore nesciunt numquam. Id itaque in sed sapiente blanditiis necessitatibus. consectetur adipisicing elit. Debitis officiis maiores quia unde, hic quisquam odit ea quo ipsam possimus, consectetur adipisicing elit. Debitis officiis maiores quia unde, hic quisquam odit ea quo ipsam possimus, + + + + + + Contact + + + - - button-icon-left-SVG-Mock - + + + button-icon-left-SVG-Mock + + + - + > + contact@venue.com + - - contact@venue.com - - - - - - button-icon-left-SVG-Mock - + + + button-icon-left-SVG-Mock + + + - + > + +33102030405 + - - +33102030405 - - - - - - button-icon-left-SVG-Mock - + + + button-icon-left-SVG-Mock + + + - + > + https://my@website.com + - - https://my@website.com - - - - - - - Accessibilité - - - + + + + Accessibilité + + + - - - undefined-SVG-Mock - + + + + undefined-SVG-Mock + + + + + + + valid-icon-SVG-Mock + + + - - - - valid-icon-SVG-Mock - - - + Handicap visuel + - - - Handicap visuel - - - - - - undefined-SVG-Mock - + + + + undefined-SVG-Mock + + + + + + + invalid-icon-SVG-Mock + + + - - - - invalid-icon-SVG-Mock - - - + Handicap psychique ou cognitif + - - - Handicap psychique ou cognitif - - - - - - undefined-SVG-Mock - + + + + undefined-SVG-Mock + + + + + + + invalid-icon-SVG-Mock + + + - - - - invalid-icon-SVG-Mock - - - - - - - Handicap moteur - + "color": "#161617", + "fontFamily": "Montserrat-SemiBold", + "fontSize": 12, + "lineHeight": 19.2, + "paddingHorizontal": 1, + "textAlign": "center", + }, + ] + } + > + Handicap moteur + + - - - - - undefined-SVG-Mock - + + + + undefined-SVG-Mock + + + + + + + invalid-icon-SVG-Mock + + + - - - - invalid-icon-SVG-Mock - - - + Handicap auditif + - - - Handicap auditif - - - - - - - Horaires d’ouverture - - - - - Lundi - - - 09:00 - 19:00 - - + /> + + - - Mardi - - - 09:00 - 12:00 / 14:00 - 19:00 - - + Horaires d’ouverture + + - + + Lundi + + + 09:00 - 19:00 + + + - Mercredi - - + Mardi + + + 09:00 - 12:00 / 14:00 - 19:00 + + + - 09:00 - 12:00 / 14:00 - 19:00 - - - - + Mercredi + + + 09:00 - 12:00 / 14:00 - 19:00 + + + - Jeudi - - + Jeudi + + + 09:00 - 12:00 / 14:00 - 19:00 + + + - 09:00 - 12:00 / 14:00 - 19:00 - - - - + Vendredi + + + 09:00 - 19:00 + + + - Vendredi - - + Samedi + + + Fermé + + + - 09:00 - 19:00 - + + Dimanche + + + Fermé + + - - Samedi - - - Fermé - - + /> - - Dimanche - - - Fermé - - + "backgroundColor": "#F1F1F4", + "height": 1, + "width": "100%", + }, + ] + } + /> + - - - - - - - - + + - - - undefined-SVG-Mock - + + + undefined-SVG-Mock + + - - - - - - Fan de lecture ? - - - Reçois nos recos lecture, nos jeux-concours et le meilleur de l’actu littéraire ! - + + - - - undefined-Lottie-Mock - - + > + Fan de lecture ? + should match snapshot with practical information 1`] = ` ] } > - Suivre le thème + Reçois nos recos lecture, nos jeux-concours et le meilleur de l’actu littéraire ! + + + + undefined-Lottie-Mock + + + + Suivre le thème + + + + + - - - - - - + - - Passe le bon plan ! - + + Passe le bon plan ! + - - undefined-SVG-Mock + + + + undefined-SVG-Mock + + + + + + Envoyer sur +Instagram - - - Envoyer sur -Instagram - - - - - - - - undefined-SVG-Mock - - - - - - Envoyer sur + + + + + undefined-SVG-Mock + + + + + + Envoyer sur WhatsApp - + + + - - - - - - undefined-SVG-Mock + + + + undefined-SVG-Mock + + + + + + Envoyer sur +iMessage - - - Envoyer sur -iMessage - - - - - - - undefined-SVG-Mock - + + + + undefined-SVG-Mock + + + + + + Plus +d’options + - - - Plus -d’options - + + + - - - - diff --git a/src/features/venue/components/VenueBody/VenueBody.native.test.tsx b/src/features/venue/components/VenueBody/VenueBody.native.test.tsx index 6a0a2bd8d5c..9e771c09d9e 100644 --- a/src/features/venue/components/VenueBody/VenueBody.native.test.tsx +++ b/src/features/venue/components/VenueBody/VenueBody.native.test.tsx @@ -1,7 +1,6 @@ import mockdate from 'mockdate' import React from 'react' import { Linking } from 'react-native' -import Share, { Social } from 'react-native-share' import { UseQueryResult } from 'react-query' import { useRoute } from '__mocks__/@react-navigation/native' @@ -14,7 +13,6 @@ import { VenueOffersResponseSnap } from 'features/venue/fixtures/venueOffersResp import { VenueOffers } from 'features/venue/types' import { analytics } from 'libs/analytics' import * as useFeatureFlag from 'libs/firebase/firestore/featureFlags/useFeatureFlag' -import { Network } from 'libs/share/types' import { reactQueryProviderHOC } from 'tests/reactQueryProviderHOC' import { fireEvent, render, screen } from 'tests/utils' @@ -24,7 +22,6 @@ mockdate.set(new Date('2021-08-15T00:00:00Z')) jest.mock('features/venue/api/useVenue') jest.mock('@react-native-clipboard/clipboard') -const mockShareSingle = jest.spyOn(Share, 'shareSingle') const canOpenURLSpy = jest.spyOn(Linking, 'canOpenURL').mockResolvedValue(false) jest .spyOn(useGTLPlaylists, 'useGTLPlaylists') @@ -52,33 +49,14 @@ describe('', () => { it('should display withdrawal details', async () => { render(reactQueryProviderHOC()) - await waitUntilRendered() fireEvent.press(screen.getByText('Infos pratiques')) expect(screen.getByText('How to withdraw, https://test.com')).toBeOnTheScreen() }) - it('should share on Instagram', async () => { - render(reactQueryProviderHOC()) - - const instagramButton = await screen.findByText(`Envoyer sur ${Network.instagram}`) - - fireEvent.press(instagramButton) - - expect(mockShareSingle).toHaveBeenCalledWith({ - social: Social.Instagram, - message: encodeURIComponent( - `Retrouve "${venueDataTest.name}" sur le pass Culture\u00a0:\nhttps://webapp-v2.example.com/lieu/5543?utm_gen=product&utm_campaign=share_venue&utm_medium=social_media&utm_source=Instagram` - ), - type: 'text', - url: undefined, - }) - }) - it('should log event when pressing on Infos pratiques tab', async () => { render(reactQueryProviderHOC()) - await waitUntilRendered() fireEvent.press(screen.getByText('Infos pratiques')) @@ -89,16 +67,9 @@ describe('', () => { it('should log event when pressing on Offres disponibles tab', async () => { render(reactQueryProviderHOC()) - await waitUntilRendered() fireEvent.press(screen.getByText('Offres disponibles')) expect(analytics.logConsultVenueOffers).toHaveBeenCalledWith({ venueId: venueDataTest.id }) }) }) - -const waitUntilRendered = async () => { - // We wait until the full render is done - // This is due to asynchronous calls to check the media on the phone - await screen.findByText(`Envoyer sur ${Network.instagram}`) -} diff --git a/src/features/venue/components/VenueBody/VenueBody.tsx b/src/features/venue/components/VenueBody/VenueBody.tsx index 9a139bf423a..c8934060bdd 100644 --- a/src/features/venue/components/VenueBody/VenueBody.tsx +++ b/src/features/venue/components/VenueBody/VenueBody.tsx @@ -6,22 +6,17 @@ import { VenueResponse } from 'api/gen' import { GtlPlaylistData } from 'features/gtlPlaylist/types' import { PracticalInformation } from 'features/venue/components/PracticalInformation/PracticalInformation' import { TabLayout } from 'features/venue/components/TabLayout/TabLayout' -import { VENUE_CTA_HEIGHT_IN_SPACES } from 'features/venue/components/VenueCTA/VenueCTA' -import { VenueMessagingApps } from 'features/venue/components/VenueMessagingApps/VenueMessagingApps' import { VenueOffers } from 'features/venue/components/VenueOffers/VenueOffers' -import { VenueThematicSection } from 'features/venue/components/VenueThematicSection/VenueThematicSection' import type { VenueOffersArtists, VenueOffers as VenueOffersType } from 'features/venue/types' import { Tab } from 'features/venue/types' import { analytics } from 'libs/analytics' import { SectionWithDivider } from 'ui/components/SectionWithDivider' -import { Spacer } from 'ui/theme' interface Props { venue: VenueResponse venueArtists?: VenueOffersArtists venueOffers?: VenueOffersType playlists?: GtlPlaylistData[] - shouldDisplayCTA?: boolean } export const VenueBody: FunctionComponent = ({ @@ -29,12 +24,11 @@ export const VenueBody: FunctionComponent = ({ venueArtists, venueOffers, playlists, - shouldDisplayCTA, }) => { const { isDesktopViewport, isTabletViewport } = useTheme() const isLargeScreen = isDesktopViewport || isTabletViewport - const FirstSectionContainer = isLargeScreen ? View : SectionWithDivider + const SectionContainer = isLargeScreen ? View : SectionWithDivider const tabPanels = { [Tab.OFFERS]: ( @@ -49,37 +43,22 @@ export const VenueBody: FunctionComponent = ({ } return ( - - - - analytics.logConsultVenueOffers({ - venueId: venue.id, - }), - 'Infos pratiques': () => - analytics.logConsultPracticalInformations({ - venueId: venue.id, - }), - }} - /> - - - - - - - - - - - - - - - + + + analytics.logConsultVenueOffers({ + venueId: venue.id, + }), + 'Infos pratiques': () => + analytics.logConsultPracticalInformations({ + venueId: venue.id, + }), + }} + /> + ) } diff --git a/src/features/venue/components/VenueCTA/VenueCTA.native.test.tsx b/src/features/venue/components/VenueCTA/VenueCTA.native.test.tsx index 5695cf3bac0..883a1f9709d 100644 --- a/src/features/venue/components/VenueCTA/VenueCTA.native.test.tsx +++ b/src/features/venue/components/VenueCTA/VenueCTA.native.test.tsx @@ -4,10 +4,10 @@ import { push } from '__mocks__/@react-navigation/native' import { SearchState } from 'features/search/types' import { VenueCTA } from 'features/venue/components/VenueCTA/VenueCTA' import { venueDataTest } from 'features/venue/fixtures/venueDataTest' -import * as useNavigateToSearchWithVenueOffers from 'features/venue/helpers/useNavigateToSearchWithVenueOffers' +import { SearchNavConfig } from 'features/venue/types' import { analytics } from 'libs/analytics' import { LocationMode } from 'libs/location/types' -import { fireEvent, render, screen, waitFor } from 'tests/utils' +import { render, screen, userEvent, waitFor } from 'tests/utils' const defaultParams: SearchState = { beginningDatetime: undefined, @@ -34,27 +34,28 @@ const defaultParams: SearchState = { }, } as SearchState -jest - .spyOn(useNavigateToSearchWithVenueOffers, 'useNavigateToSearchWithVenueOffers') - .mockReturnValue({ - screen: 'TabNavigator', +const searchNavConfigMock: SearchNavConfig = { + screen: 'TabNavigator', + params: { + screen: 'SearchStackNavigator', params: { - screen: 'SearchStackNavigator', - params: { - screen: 'SearchResults', - params: defaultParams, - }, + screen: 'SearchResults', + params: defaultParams, }, - withPush: true, - }) + }, + withPush: true, +} jest.mock('libs/firebase/analytics/analytics') +jest.useFakeTimers() +const user = userEvent.setup() + describe('', () => { it('should navigate to the search page when pressed on', async () => { - render() + render() - fireEvent.press(screen.getByText('Rechercher une offre')) + await user.press(await screen.findByText('Rechercher une offre')) await waitFor(() => { expect(push).toHaveBeenCalledWith('TabNavigator', { @@ -76,9 +77,14 @@ describe('', () => { }) it('should log event when pressed on', async () => { - render() + render( + analytics.logVenueSeeAllOffersClicked(venueDataTest.id)} + /> + ) - fireEvent.press(screen.getByText('Rechercher une offre')) + await user.press(await screen.findByText('Rechercher une offre')) expect(analytics.logVenueSeeAllOffersClicked).toHaveBeenCalledWith(venueDataTest.id) }) diff --git a/src/features/venue/components/VenueCTA/VenueCTA.tsx b/src/features/venue/components/VenueCTA/VenueCTA.tsx index 9b7096e527f..042ef076204 100644 --- a/src/features/venue/components/VenueCTA/VenueCTA.tsx +++ b/src/features/venue/components/VenueCTA/VenueCTA.tsx @@ -1,9 +1,7 @@ import React, { FunctionComponent } from 'react' import styled from 'styled-components/native' -import { VenueResponse } from 'api/gen' -import { useNavigateToSearchWithVenueOffers } from 'features/venue/helpers/useNavigateToSearchWithVenueOffers' -import { analytics } from 'libs/analytics' +import { SearchNavConfig } from 'features/venue/types' import { ButtonPrimary } from 'ui/components/buttons/ButtonPrimary' import { StickyBottomWrapper } from 'ui/components/StickyBottomWrapper/StickyBottomWrapper' import { InternalTouchableLink } from 'ui/components/touchableLink/InternalTouchableLink' @@ -13,18 +11,18 @@ import { Spacer } from 'ui/theme' export const VENUE_CTA_HEIGHT_IN_SPACES = 6 + 10 + 6 interface Props { - venue: VenueResponse + searchNavConfig: SearchNavConfig + onBeforeNavigate: () => void } -export const VenueCTA: FunctionComponent = ({ venue }) => { - const searchNavConfig = useNavigateToSearchWithVenueOffers(venue) +export const VenueCTA: FunctionComponent = ({ searchNavConfig, onBeforeNavigate }) => { return ( analytics.logVenueSeeAllOffersClicked(venue.id)} + onBeforeNavigate={onBeforeNavigate} as={ButtonPrimary} wording="Rechercher une offre" icon={SmallMagnifyingGlass} diff --git a/src/features/venue/components/VenueContent/VenueContent.native.test.tsx b/src/features/venue/components/VenueContent/VenueContent.native.test.tsx index 64ee313c000..307aa977fa6 100644 --- a/src/features/venue/components/VenueContent/VenueContent.native.test.tsx +++ b/src/features/venue/components/VenueContent/VenueContent.native.test.tsx @@ -3,28 +3,17 @@ import React, { createRef } from 'react' import { ScrollView } from 'react-native' import { push } from '__mocks__/@react-navigation/native' -import { VenueTypeCodeKey } from 'api/gen' -import { CineContentCTAID } from 'features/offer/components/OfferCine/CineContentCTA' import { OfferCTAProvider } from 'features/offer/components/OfferContent/OfferCTAProvider' import { VenueContent } from 'features/venue/components/VenueContent/VenueContent' import { venueDataTest } from 'features/venue/fixtures/venueDataTest' -import { - VenueMoviesOffersResponseSnap, - VenueOffersResponseSnap, -} from 'features/venue/fixtures/venueOffersResponseSnap' -import { DEFAULT_REMOTE_CONFIG } from 'libs/firebase/remoteConfig/remoteConfig.constants' -import * as useRemoteConfigContextModule from 'libs/firebase/remoteConfig/RemoteConfigProvider' import { LocationMode } from 'libs/location/types' import { BatchEvent, BatchProfile } from 'libs/react-native-batch' import { reactQueryProviderHOC } from 'tests/reactQueryProviderHOC' -import { act, fireEvent, render, screen, userEvent, waitFor } from 'tests/utils' -import * as AnchorContextModule from 'ui/components/anchor/AnchorContext' +import { act, render, screen, userEvent, waitFor } from 'tests/utils' import { AnchorProvider } from 'ui/components/anchor/AnchorContext' import * as useModalAPI from 'ui/components/modals/useModal' -const useScrollToAnchorSpy = jest.spyOn(AnchorContextModule, 'useScrollToAnchor') - -let mockFFValue = false +const mockFFValue = false jest.mock('libs/firebase/firestore/featureFlags/useFeatureFlag', () => ({ useFeatureFlag: () => mockFFValue, })) @@ -67,8 +56,6 @@ jest.mock('react-native-intersection-observer', () => { } }) -const useRemoteConfigContextSpy = jest.spyOn(useRemoteConfigContextModule, 'useRemoteConfigContext') - const defaultSearchParams = { beginningDatetime: undefined, date: null, @@ -101,20 +88,22 @@ const renderVenueContent = (props?: Partial()} handleCheckScrollY={() => 0}> - + + + ) ) } +const user = userEvent.setup() + describe('', () => { it('should search the offers associated when pressing "Rechercher une offre"', async () => { - renderVenueContent({ - venueOffers: { hits: VenueOffersResponseSnap, nbHits: 4 }, - }) + renderVenueContent({ isCTADisplayed: true }) - fireEvent.press(screen.getByText('Rechercher une offre')) + await user.press(screen.getByText('Rechercher une offre')) await waitFor(() => { expect(push).toHaveBeenCalledWith('TabNavigator', { @@ -163,97 +152,4 @@ describe('', () => { expect(BatchProfile.trackEvent).not.toHaveBeenCalled() }) }) - - it('should display default background image when no banner for venue', async () => { - renderVenueContent() - - expect(await screen.findByTestId('defaultVenueBackground')).toBeOnTheScreen() - }) - - describe('movie screening access button', () => { - beforeAll(() => { - useRemoteConfigContextSpy.mockReturnValue({ - ...DEFAULT_REMOTE_CONFIG, - showAccessScreeningButton: true, - }) - }) - - const venueMoviesOffersMock = { hits: VenueMoviesOffersResponseSnap, nbHits: 4 } - mockFFValue = true - - // TODO(PC-33563): fix flaky tests - // eslint-disable-next-line jest/no-disabled-tests - it.skip('should show button', async () => { - renderVenueContent({ - venue: { ...venueDataTest, venueTypeCode: VenueTypeCodeKey.MOVIE }, - venueOffers: venueMoviesOffersMock, - }) - await act(async () => { - mockInView(false) - }) - - await screen.findByText('Les films à l’affiche') - - expect(await screen.findByTestId(CineContentCTAID)).toBeOnTheScreen() - }) - - it('should not show button', async () => { - renderVenueContent({ - venue: { ...venueDataTest, venueTypeCode: VenueTypeCodeKey.MOVIE }, - venueOffers: venueMoviesOffersMock, - }) - await act(async () => { - mockInView(true) - }) - - await screen.findByText('Les films à l’affiche') - - expect(screen.queryByTestId(CineContentCTAID)).not.toBeOnTheScreen() - }) - - // TODO(PC-33563): fix flaky tests - // eslint-disable-next-line jest/no-disabled-tests - it.skip('should scroll to anchor', async () => { - renderVenueContent({ - venue: { ...venueDataTest, venueTypeCode: VenueTypeCodeKey.MOVIE }, - venueOffers: venueMoviesOffersMock, - }) - - await act(async () => { - mockInView(false) - }) - - const button = await screen.findByTestId(CineContentCTAID) - - await userEvent.press(button) - - expect(useScrollToAnchorSpy).toHaveBeenCalledWith() - }) - - // TODO(PC-33563): fix flaky tests - // eslint-disable-next-line jest/no-disabled-tests - describe.skip('remote config flag is deactivated', () => { - beforeAll(() => { - useRemoteConfigContextSpy.mockReturnValue({ - ...DEFAULT_REMOTE_CONFIG, - showAccessScreeningButton: false, - }) - }) - - it('should not display the button if the remote config flag is deactivated', async () => { - renderVenueContent({ - venue: { ...venueDataTest, venueTypeCode: VenueTypeCodeKey.MOVIE }, - venueOffers: venueMoviesOffersMock, - }) - - await act(async () => { - mockInView(false) - }) - - await screen.findByText('Les films à l’affiche') - - expect(screen.queryByTestId(CineContentCTAID)).not.toBeOnTheScreen() - }) - }) - }) }) diff --git a/src/features/venue/components/VenueContent/VenueContent.tsx b/src/features/venue/components/VenueContent/VenueContent.tsx index d513ea2957f..7c89d8de2fb 100644 --- a/src/features/venue/components/VenueContent/VenueContent.tsx +++ b/src/features/venue/components/VenueContent/VenueContent.tsx @@ -1,44 +1,37 @@ import React, { useCallback, useEffect, useRef } from 'react' -import { NativeScrollEvent, NativeSyntheticEvent, Platform, ScrollView } from 'react-native' +import { NativeScrollEvent, NativeSyntheticEvent, ScrollView } from 'react-native' import { IOScrollView as IntersectionObserverScrollView } from 'react-native-intersection-observer' -import Animated, { Layout } from 'react-native-reanimated' import styled, { useTheme } from 'styled-components/native' -import { VenueResponse, VenueTypeCodeKey } from 'api/gen' -import { GtlPlaylistData } from 'features/gtlPlaylist/types' +import { VenueResponse } from 'api/gen' import { CineContentCTA } from 'features/offer/components/OfferCine/CineContentCTA' import { useOfferCTA } from 'features/offer/components/OfferContent/OfferCTAProvider' -import { VenueBody } from 'features/venue/components/VenueBody/VenueBody' +import { VenueHeaderWrapper } from 'features/venue/components/VenueContent/VenueHeaderWrapper' import { VenueCTA } from 'features/venue/components/VenueCTA/VenueCTA' import { VenueHeader } from 'features/venue/components/VenueHeader/VenueHeader' -import { VenueTopComponent } from 'features/venue/components/VenueTopComponent/VenueTopComponent' import { VenueWebMetaHeader } from 'features/venue/components/VenueWebMetaHeader' -import { VenueOffers, VenueOffersArtists } from 'features/venue/types' -import { isCloseToBottom } from 'libs/analytics' +import { useNavigateToSearchWithVenueOffers } from 'features/venue/helpers/useNavigateToSearchWithVenueOffers' +import { analytics, isCloseToBottom } from 'libs/analytics' import { useRemoteConfigContext } from 'libs/firebase/remoteConfig/RemoteConfigProvider' import { useFunctionOnce } from 'libs/hooks' import { BatchEvent, BatchProfile } from 'libs/react-native-batch' import { useOpacityTransition } from 'ui/animations/helpers/useOpacityTransition' import { AnchorProvider } from 'ui/components/anchor/AnchorContext' import { useGetHeaderHeight } from 'ui/components/headers/PageHeaderWithoutPlaceholder' -import { Spacer } from 'ui/theme' type Props = { venue: VenueResponse - gtlPlaylists?: GtlPlaylistData[] - venueArtists?: VenueOffersArtists - venueOffers?: VenueOffers + isCTADisplayed?: boolean + children: React.ReactNode } const trackEventHasSeenVenueForSurvey = () => BatchProfile.trackEvent(BatchEvent.hasSeenVenueForSurvey) -const isWeb = Platform.OS === 'web' export const VenueContent: React.FunctionComponent = ({ venue, - gtlPlaylists, - venueArtists, - venueOffers, + isCTADisplayed, + children, }) => { const triggerBatch = useFunctionOnce(trackEventHasSeenVenueForSurvey) const scrollViewRef = useRef(null) @@ -77,44 +70,45 @@ export const VenueContent: React.FunctionComponent = ({ const headerHeight = useGetHeaderHeight() const isLargeScreen = isDesktopViewport || isTabletViewport const { isButtonVisible, wording } = useOfferCTA() - - const shouldDisplayCTA = - venue.venueTypeCode !== VenueTypeCodeKey.MOVIE && - ((venueOffers && venueOffers.hits.length > 0) || (gtlPlaylists && gtlPlaylists.length > 0)) + const searchNavConfig = useNavigateToSearchWithVenueOffers(venue) const renderVenueCTA = useCallback(() => { if (showAccessScreeningButton && wording.length) { return isButtonVisible ? : null } - return shouldDisplayCTA ? : null - }, [isButtonVisible, shouldDisplayCTA, showAccessScreeningButton, venue, wording.length]) + return isCTADisplayed ? ( + analytics.logVenueSeeAllOffersClicked(venue.id)} + /> + ) : null + }, [ + isButtonVisible, + isCTADisplayed, + showAccessScreeningButton, + venue.id, + wording.length, + searchNavConfig, + ]) return ( - - {/* On web VenueHeader is called before Body for accessibility navigate order */} - {isWeb ? : null} - - {isLargeScreen ? : null} - - - - - - - {/* On native VenueHeader is called after Body to implement the BlurView for iOS */} - {isWeb ? null : } + + }> + + {isLargeScreen ? : null} + {children} + + {renderVenueCTA()} @@ -131,7 +125,6 @@ const ContentContainer = styled(IntersectionObserverScrollView).attrs({ })({ overflow: 'visible', }) - const Placeholder = styled.View<{ height: number }>(({ height }) => ({ height, })) diff --git a/src/features/venue/components/VenueContent/VenueHeaderWrapper.tsx b/src/features/venue/components/VenueContent/VenueHeaderWrapper.tsx new file mode 100644 index 00000000000..9037f531612 --- /dev/null +++ b/src/features/venue/components/VenueContent/VenueHeaderWrapper.tsx @@ -0,0 +1,16 @@ +import React from 'react' + +type Props = { + children: React.ReactNode + header?: React.ReactNode +} + +/* On native VenueHeader is called after Body to implement the BlurView for iOS */ +export const VenueHeaderWrapper = ({ children, header }: Props) => { + return ( + + {children} + {header} + + ) +} diff --git a/src/features/venue/components/VenueContent/VenueHeaderWrapper.web.tsx b/src/features/venue/components/VenueContent/VenueHeaderWrapper.web.tsx new file mode 100644 index 00000000000..680513831d0 --- /dev/null +++ b/src/features/venue/components/VenueContent/VenueHeaderWrapper.web.tsx @@ -0,0 +1,16 @@ +import React from 'react' + +type Props = { + children: React.ReactNode + header?: React.ReactNode +} + +/* On web VenueHeader is called before Body for accessibility navigate order */ +export const VenueHeaderWrapper = ({ children, header }: Props) => { + return ( + + {header} + {children} + + ) +} diff --git a/src/features/venue/components/VenueMessagingApps/VenueMessagingApps.tsx b/src/features/venue/components/VenueMessagingApps/VenueMessagingApps.tsx index d95b985c042..761f3ab2c48 100644 --- a/src/features/venue/components/VenueMessagingApps/VenueMessagingApps.tsx +++ b/src/features/venue/components/VenueMessagingApps/VenueMessagingApps.tsx @@ -1,10 +1,13 @@ import React, { useCallback } from 'react' import { Social } from 'react-native-share' +import styled from 'styled-components/native' import { VenueResponse } from 'api/gen' import { MessagingApps } from 'features/share/components/MessagingApps/MessagingApps' import { getShareVenue } from 'features/share/helpers/getShareVenue' import { analytics } from 'libs/analytics' +import { SectionWithDivider } from 'ui/components/SectionWithDivider' +import { getSpacing } from 'ui/theme' type MessagingAppsProps = { venue: VenueResponse @@ -23,10 +26,16 @@ export const VenueMessagingApps = ({ venue }: MessagingAppsProps) => { if (!shareContent?.url) return null return ( - + + + + + ) } + +const Container = styled.View({ marginBottom: getSpacing(4) }) diff --git a/src/features/venue/components/VenueThematicSection/VenueThematicSection.tsx b/src/features/venue/components/VenueThematicSection/VenueThematicSection.tsx index a3f8c26f292..0e6d12e599d 100644 --- a/src/features/venue/components/VenueThematicSection/VenueThematicSection.tsx +++ b/src/features/venue/components/VenueThematicSection/VenueThematicSection.tsx @@ -85,7 +85,7 @@ export const VenueThematicSection: FunctionComponent = ({ venue }: Props) return null return ( - + = ({ handleImagePress={onPressBannerImage} /> - - - - - {venueName} - - {isDynamicOpeningHoursDisplayed ? ( - - ) : null} - - - Adresse - {venueFullAddress} - - - analytics.logCopyAddress({ venueId: venue.id, from: 'venue' })} - snackBarMessage="L’adresse a bien été copiée." - /> - analytics.logConsultItinerary({ venueId: venue.id, from: 'venue' })} - /> + + + + + {venueName} + + {isDynamicOpeningHoursDisplayed ? ( + + ) : null} + + + Adresse + {venueFullAddress} + + + analytics.logCopyAddress({ venueId: venue.id, from: 'venue' })} + snackBarMessage="L’adresse a bien été copiée." + /> + analytics.logConsultItinerary({ venueId: venue.id, from: 'venue' })} + /> + diff --git a/src/features/venue/components/VenueWebMetaHeader.tsx b/src/features/venue/components/VenueWebMetaHeader.tsx index 5d9153af2a2..0ea55673324 100644 --- a/src/features/venue/components/VenueWebMetaHeader.tsx +++ b/src/features/venue/components/VenueWebMetaHeader.tsx @@ -1,18 +1,18 @@ import React from 'react' -import { VenueResponse } from 'api/gen' import { Helmet } from 'libs/react-helmet/Helmet' import { description } from '../../../../package.json' interface Props { - venue: VenueResponse + title: string + description?: string | null } -export const VenueWebMetaHeader = ({ venue }: Props) => ( +export const VenueWebMetaHeader = (props: Props) => ( - {(venue.publicName || venue.name) + ' | pass Culture'} - - + {props.title + ' | pass Culture'} + + ) diff --git a/src/features/venue/pages/Venue/Venue.native.test.tsx b/src/features/venue/pages/Venue/Venue.native.test.tsx index c71e94bfa1e..7e868491c14 100644 --- a/src/features/venue/pages/Venue/Venue.native.test.tsx +++ b/src/features/venue/pages/Venue/Venue.native.test.tsx @@ -4,17 +4,28 @@ import mockdate from 'mockdate' import React from 'react' import { useRoute } from '__mocks__/@react-navigation/native' -import { SubcategoryIdEnum, VenueResponse } from 'api/gen' +import { SubcategoryIdEnum, VenueResponse, VenueTypeCodeKey } from 'api/gen' import { useGTLPlaylists } from 'features/gtlPlaylist/hooks/useGTLPlaylists' import { Referrals } from 'features/navigation/RootNavigator/types' +import { CineContentCTAID } from 'features/offer/components/OfferCine/CineContentCTA' +import { useVenueOffers } from 'features/venue/api/useVenueOffers' import { venueDataTest } from 'features/venue/fixtures/venueDataTest' +import { + VenueMoviesOffersResponseSnap, + VenueOffersResponseSnap, +} from 'features/venue/fixtures/venueOffersResponseSnap' import { Venue } from 'features/venue/pages/Venue/Venue' import { analytics } from 'libs/analytics' import { setFeatureFlags } from 'libs/firebase/firestore/featureFlags/__tests__/setFeatureFlags' +import { RemoteStoreFeatureFlags } from 'libs/firebase/firestore/types' +import { DEFAULT_REMOTE_CONFIG } from 'libs/firebase/remoteConfig/remoteConfig.constants' +import * as useRemoteConfigContextModule from 'libs/firebase/remoteConfig/RemoteConfigProvider' +import { Network } from 'libs/share/types' import { Offer } from 'shared/offer/types' import { mockServer } from 'tests/mswServer' import { reactQueryProviderHOC } from 'tests/reactQueryProviderHOC' -import { fireEvent, render, screen, waitFor } from 'tests/utils' +import { render, screen, userEvent, waitFor } from 'tests/utils' +import * as AnchorContextModule from 'ui/components/anchor/AnchorContext' const getItemSpy = jest.spyOn(AsyncStorage, 'getItem') @@ -28,6 +39,8 @@ jest.unmock('react-native/Libraries/Animated/createAnimatedComponent') jest.mock('libs/itinerary/useItinerary') jest.mock('features/venue/api/useVenueOffers') +const mockUseVenueOffers = useVenueOffers as jest.Mock + jest.mock('features/search/context/SearchWrapper') jest.mock('libs/location') @@ -83,7 +96,19 @@ jest.mock('@shopify/flash-list', () => { } }) +const useRemoteConfigContextSpy = jest.spyOn(useRemoteConfigContextModule, 'useRemoteConfigContext') +const useScrollToAnchorSpy = jest.spyOn(AnchorContextModule, 'useScrollToAnchor') + +const user = userEvent.setup() + describe('', () => { + beforeAll(() => { + mockUseVenueOffers.mockReturnValue({ + isLoading: false, + data: { hits: VenueOffersResponseSnap, nbHits: 3 }, + }) + }) + beforeEach(() => { setFeatureFlags() getItemSpy.mockReset() @@ -93,7 +118,7 @@ describe('', () => { it('should match snapshot', async () => { renderVenue(venueId) - await screen.findByText('Infos pratiques') + await screen.findByText(`Envoyer sur ${Network.instagram}`) expect(screen).toMatchSnapshot() }) @@ -101,11 +126,17 @@ describe('', () => { it('should match snapshot with practical information', async () => { renderVenue(venueId) - fireEvent.press(await screen.findByText('Infos pratiques')) + await user.press(await screen.findByText('Infos pratiques')) expect(screen).toMatchSnapshot() }) + it('should display default background image when no banner for venue', async () => { + renderVenue(venueId) + + expect(await screen.findByTestId('defaultVenueBackground')).toBeOnTheScreen() + }) + describe('analytics', () => { it.each([['deeplink'], ['venueMap']])( 'should log consult venue when URL from param equal to %s', @@ -137,6 +168,75 @@ describe('', () => { expect(analytics.logConsultVenue).not.toHaveBeenCalled() }) }) + + describe('movie screening access button', () => { + beforeAll(() => { + useRemoteConfigContextSpy.mockReturnValue({ + ...DEFAULT_REMOTE_CONFIG, + showAccessScreeningButton: true, + }) + mockUseVenueOffers.mockReturnValue({ + isLoading: false, + data: { hits: VenueMoviesOffersResponseSnap, nbHits: 4 }, + }) + mockServer.getApi(`/v1/venue/${venueId}`, { + ...venueDataTest, + venueTypeCode: VenueTypeCodeKey.MOVIE, + }) + + setFeatureFlags([RemoteStoreFeatureFlags.WIP_ENABLE_NEW_XP_CINE_FROM_VENUE]) + }) + + // TODO(PC-33563): fix flaky tests + // eslint-disable-next-line jest/no-disabled-tests + it.skip('should show button', async () => { + renderVenue(venueId) + await screen.findByText('Les films à l’affiche') + + expect(await screen.findByTestId(CineContentCTAID)).toBeOnTheScreen() + }) + + // TODO(PC-33563): fix flaky tests + // eslint-disable-next-line jest/no-disabled-tests + it.skip('should not show button', async () => { + renderVenue(venueId) + + await screen.findByText('Les films à l’affiche') + + expect(screen.queryByTestId(CineContentCTAID)).not.toBeOnTheScreen() + }) + + // TODO(PC-33563): fix flaky tests + // eslint-disable-next-line jest/no-disabled-tests + it.skip('should scroll to anchor', async () => { + renderVenue(venueId) + + const button = await screen.findByTestId(CineContentCTAID) + + await userEvent.press(button) + + expect(useScrollToAnchorSpy).toHaveBeenCalledWith() + }) + + // TODO(PC-33563): fix flaky tests + // eslint-disable-next-line jest/no-disabled-tests + describe.skip('remote config flag is deactivated', () => { + beforeAll(() => { + useRemoteConfigContextSpy.mockReturnValue({ + ...DEFAULT_REMOTE_CONFIG, + showAccessScreeningButton: false, + }) + }) + + it('should not display the button if the remote config flag is deactivated', async () => { + renderVenue(venueId) + + await screen.findByText('Les films à l’affiche') + + expect(screen.queryByTestId(CineContentCTAID)).not.toBeOnTheScreen() + }) + }) + }) }) async function renderVenue(id: number, from?: Referrals) { diff --git a/src/features/venue/pages/Venue/Venue.tsx b/src/features/venue/pages/Venue/Venue.tsx index d800e508f88..8627e8224bf 100644 --- a/src/features/venue/pages/Venue/Venue.tsx +++ b/src/features/venue/pages/Venue/Venue.tsx @@ -1,14 +1,25 @@ import { useRoute } from '@react-navigation/native' import React, { FunctionComponent, useEffect } from 'react' +import Animated, { Layout } from 'react-native-reanimated' +import styled, { useTheme } from 'styled-components/native' +import { VenueTypeCodeKey } from 'api/gen' import { useGTLPlaylists } from 'features/gtlPlaylist/hooks/useGTLPlaylists' import { UseRouteType } from 'features/navigation/RootNavigator/types' import { OfferCTAProvider } from 'features/offer/components/OfferContent/OfferCTAProvider' import { useVenue } from 'features/venue/api/useVenue' import { useVenueOffers } from 'features/venue/api/useVenueOffers' import { useVenueOffersArtists } from 'features/venue/api/useVenueOffersArtists/useVenueOffersArtists' +import { VenueBody } from 'features/venue/components/VenueBody/VenueBody' import { VenueContent } from 'features/venue/components/VenueContent/VenueContent' +import { VENUE_CTA_HEIGHT_IN_SPACES } from 'features/venue/components/VenueCTA/VenueCTA' +import { VenueMessagingApps } from 'features/venue/components/VenueMessagingApps/VenueMessagingApps' +import { VenueThematicSection } from 'features/venue/components/VenueThematicSection/VenueThematicSection' +import { VenueTopComponent } from 'features/venue/components/VenueTopComponent/VenueTopComponent' import { analytics } from 'libs/analytics' +import { SectionWithDivider } from 'ui/components/SectionWithDivider' +import { ViewGap } from 'ui/components/ViewGap/ViewGap' +import { getSpacing } from 'ui/theme' export const Venue: FunctionComponent = () => { const { params } = useRoute>() @@ -16,6 +27,7 @@ export const Venue: FunctionComponent = () => { const { gtlPlaylists } = useGTLPlaylists({ venue, queryKey: 'VENUE_GTL_PLAYLISTS' }) const { data: venueOffers } = useVenueOffers(venue) const { data: venueArtists } = useVenueOffersArtists(venue) + const { isDesktopViewport } = useTheme() useEffect(() => { if ((params.from === 'deeplink' || params.from === 'venueMap') && venue?.id) { @@ -23,14 +35,43 @@ export const Venue: FunctionComponent = () => { } }, [params.from, venue?.id]) + const isCTADisplayed = + venue?.venueTypeCode !== VenueTypeCodeKey.MOVIE && + ((venueOffers && venueOffers.hits.length > 0) || (gtlPlaylists && gtlPlaylists.length > 0)) + + if (!venue) return null + return venue ? ( - + + + + + + + + + + + + + + ) : null } + +const EmptyBottomSection = ({ isVisible }: { isVisible: boolean }) => { + return ( + + + + ) +} + +const EmptySectionContainer = styled.View({ marginBottom: getSpacing(6) }) diff --git a/src/features/venue/types.ts b/src/features/venue/types.ts index 3ef44d6ddec..3b659c03930 100644 --- a/src/features/venue/types.ts +++ b/src/features/venue/types.ts @@ -1,5 +1,6 @@ import { ReactNode } from 'react' +import { RootNavigateParams } from 'features/navigation/RootNavigator/types' import { Geoloc } from 'libs/algolia/types' import { VenueTypeCode } from 'libs/parsers/venueType' import { Offer } from 'shared/offer/types' @@ -68,3 +69,11 @@ export type Artist = { } export type VenueOffersArtists = { artists: Artist[] } + +export type SearchNavConfig = { + screen: RootNavigateParams[0] + params?: RootNavigateParams[1] + withPush?: boolean + withReset?: boolean + fromRef?: boolean +}