From aaa8c9b916b536aea6b418e2c39a8757ef0290d9 Mon Sep 17 00:00:00 2001 From: stylianosgakis Date: Tue, 7 Jul 2026 15:29:47 +0200 Subject: [PATCH 1/2] Consume banner and benefits fields on the addon recommendation --- .../android/apollo/octopus/schema.graphqls | 8 +++++ .../QueryBottomSheetCrossSells.graphql | 2 ++ .../sell/sheet/CrossSellSheetViewModel.kt | 2 ++ .../sell/sheet/CrossSellSheetPresenterTest.kt | 2 ++ .../src/main/graphql/QueryHome.graphql | 2 ++ .../home/home/data/GetHomeDataUseCase.kt | 2 ++ .../home/home/data/GetHomeUseCaseTest.kt | 4 +++ .../feature/home/home/ui/HomePresenterTest.kt | 2 ++ .../hedvig/android/crosssells/CrossSells.kt | 33 ++++++++++++++++++- 9 files changed, 56 insertions(+), 1 deletion(-) diff --git a/app/apollo/apollo-octopus-public/src/commonMain/graphql/com/hedvig/android/apollo/octopus/schema.graphqls b/app/apollo/apollo-octopus-public/src/commonMain/graphql/com/hedvig/android/apollo/octopus/schema.graphqls index 9b640dcbe3..78580a0fec 100644 --- a/app/apollo/apollo-octopus-public/src/commonMain/graphql/com/hedvig/android/apollo/octopus/schema.graphqls +++ b/app/apollo/apollo-octopus-public/src/commonMain/graphql/com/hedvig/android/apollo/octopus/schema.graphqls @@ -4817,6 +4817,14 @@ type RecommendedAddonCrossSell { deepLink: String! pillowImageSmall: StoryblokImageAsset! pillowImageLarge: StoryblokImageAsset! + """ + Optional banner text shown above the card; clients fall back to a default when null + """ + banner: String + """ + Benefit rows shown as a checkmark list; empty when none + """ + benefits: [String!]! } type RecommendedCrossSell { crossSell: CrossSell! diff --git a/app/feature/feature-cross-sell-sheet/src/main/graphql/QueryBottomSheetCrossSells.graphql b/app/feature/feature-cross-sell-sheet/src/main/graphql/QueryBottomSheetCrossSells.graphql index 57e42e2751..3867f5b4e6 100644 --- a/app/feature/feature-cross-sell-sheet/src/main/graphql/QueryBottomSheetCrossSells.graphql +++ b/app/feature/feature-cross-sell-sheet/src/main/graphql/QueryBottomSheetCrossSells.graphql @@ -7,6 +7,8 @@ query BottomSheetCrossSells($input: CrossSellInput!) { description buttonTitle deepLink + banner + benefits pillowImageLarge { src } diff --git a/app/feature/feature-cross-sell-sheet/src/main/kotlin/com/hedvig/android/feature/cross/sell/sheet/CrossSellSheetViewModel.kt b/app/feature/feature-cross-sell-sheet/src/main/kotlin/com/hedvig/android/feature/cross/sell/sheet/CrossSellSheetViewModel.kt index 42af3f8ebe..b51b0133ba 100644 --- a/app/feature/feature-cross-sell-sheet/src/main/kotlin/com/hedvig/android/feature/cross/sell/sheet/CrossSellSheetViewModel.kt +++ b/app/feature/feature-cross-sell-sheet/src/main/kotlin/com/hedvig/android/feature/cross/sell/sheet/CrossSellSheetViewModel.kt @@ -196,6 +196,8 @@ internal class GetCrossSellSheetDataUseCaseImpl( buttonTitle = it.buttonTitle, description = it.description, deepLink = it.deepLink, + banner = it.banner, + benefits = it.benefits, pillowImageSmall = it.pillowImageSmall.src, pillowImageLarge = it.pillowImageLarge.src, ) diff --git a/app/feature/feature-cross-sell-sheet/src/test/kotlin/com/hedvig/android/feature/cross/sell/sheet/CrossSellSheetPresenterTest.kt b/app/feature/feature-cross-sell-sheet/src/test/kotlin/com/hedvig/android/feature/cross/sell/sheet/CrossSellSheetPresenterTest.kt index 1a39e42b4a..e90f6221d2 100644 --- a/app/feature/feature-cross-sell-sheet/src/test/kotlin/com/hedvig/android/feature/cross/sell/sheet/CrossSellSheetPresenterTest.kt +++ b/app/feature/feature-cross-sell-sheet/src/test/kotlin/com/hedvig/android/feature/cross/sell/sheet/CrossSellSheetPresenterTest.kt @@ -24,6 +24,8 @@ internal class CrossSellSheetPresenterTest { buttonTitle = "See offer", description = "For a safer trip abroad", deepLink = "https://hedvig.com/addon", + banner = "Add extra safety when traveling", + benefits = listOf("Travel up to 60 days in a row"), pillowImageSmall = "smallSrc", pillowImageLarge = "largeSrc", ) diff --git a/app/feature/feature-home/src/main/graphql/QueryHome.graphql b/app/feature/feature-home/src/main/graphql/QueryHome.graphql index be16d2b2a1..330ac27cf9 100644 --- a/app/feature/feature-home/src/main/graphql/QueryHome.graphql +++ b/app/feature/feature-home/src/main/graphql/QueryHome.graphql @@ -64,6 +64,8 @@ query Home($claimsHistoryFlag: Boolean!) { description buttonTitle deepLink + banner + benefits pillowImageLarge { src } diff --git a/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/home/data/GetHomeDataUseCase.kt b/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/home/data/GetHomeDataUseCase.kt index 8754f58e2f..f2def2bd9a 100644 --- a/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/home/data/GetHomeDataUseCase.kt +++ b/app/feature/feature-home/src/main/kotlin/com/hedvig/android/feature/home/home/data/GetHomeDataUseCase.kt @@ -144,6 +144,8 @@ internal class GetHomeDataUseCaseImpl( buttonTitle = it.buttonTitle, description = it.description, deepLink = it.deepLink, + banner = it.banner, + benefits = it.benefits, pillowImageSmall = it.pillowImageSmall.src, pillowImageLarge = it.pillowImageLarge.src, ) diff --git a/app/feature/feature-home/src/test/kotlin/com/hedvig/android/feature/home/home/data/GetHomeUseCaseTest.kt b/app/feature/feature-home/src/test/kotlin/com/hedvig/android/feature/home/home/data/GetHomeUseCaseTest.kt index ddd9231d9c..4e01c7ed18 100644 --- a/app/feature/feature-home/src/test/kotlin/com/hedvig/android/feature/home/home/data/GetHomeUseCaseTest.kt +++ b/app/feature/feature-home/src/test/kotlin/com/hedvig/android/feature/home/home/data/GetHomeUseCaseTest.kt @@ -689,6 +689,8 @@ internal class GetHomeUseCaseTest { description = "For a safer trip abroad" buttonTitle = "See offer" deepLink = "https://hedvig.com/addon" + banner = "Add extra safety when traveling" + benefits = listOf("Travel up to 60 days in a row", "Delayed bags and flights covered") pillowImageSmall = buildStoryblokImageAsset { src = "smallSrc" } pillowImageLarge = buildStoryblokImageAsset { src = "largeSrc" } } @@ -719,6 +721,8 @@ internal class GetHomeUseCaseTest { buttonTitle = "See offer", description = "For a safer trip abroad", deepLink = "https://hedvig.com/addon", + banner = "Add extra safety when traveling", + benefits = listOf("Travel up to 60 days in a row", "Delayed bags and flights covered"), pillowImageSmall = "smallSrc", pillowImageLarge = "largeSrc", ), diff --git a/app/feature/feature-home/src/test/kotlin/com/hedvig/android/feature/home/home/ui/HomePresenterTest.kt b/app/feature/feature-home/src/test/kotlin/com/hedvig/android/feature/home/home/ui/HomePresenterTest.kt index c997ec6627..c72f1a1d33 100644 --- a/app/feature/feature-home/src/test/kotlin/com/hedvig/android/feature/home/home/ui/HomePresenterTest.kt +++ b/app/feature/feature-home/src/test/kotlin/com/hedvig/android/feature/home/home/ui/HomePresenterTest.kt @@ -61,6 +61,8 @@ internal class HomePresenterTest { buttonTitle = "See offer", description = "For a safer trip abroad", deepLink = "https://hedvig.com/addon", + banner = "Add extra safety when traveling", + benefits = listOf("Travel up to 60 days in a row"), pillowImageSmall = "smallSrc", pillowImageLarge = "largeSrc", ) diff --git a/app/ui/cross-sells/src/main/kotlin/com/hedvig/android/crosssells/CrossSells.kt b/app/ui/cross-sells/src/main/kotlin/com/hedvig/android/crosssells/CrossSells.kt index eadb8a14d9..38bee6ef9c 100644 --- a/app/ui/cross-sells/src/main/kotlin/com/hedvig/android/crosssells/CrossSells.kt +++ b/app/ui/cross-sells/src/main/kotlin/com/hedvig/android/crosssells/CrossSells.kt @@ -63,6 +63,7 @@ import com.hedvig.android.design.system.hedvig.Surface import com.hedvig.android.design.system.hedvig.api.HedvigBottomSheetState import com.hedvig.android.design.system.hedvig.hedvigDropShadow import com.hedvig.android.design.system.hedvig.icon.Campaign +import com.hedvig.android.design.system.hedvig.icon.Checkmark import com.hedvig.android.design.system.hedvig.icon.HedvigIcons import com.hedvig.android.design.system.hedvig.icon.Plus import com.hedvig.android.design.system.hedvig.placeholder.crossSellPainterFallback @@ -102,6 +103,8 @@ data class RecommendedAddon( val buttonTitle: String, val description: String, val deepLink: String, + val banner: String?, + val benefits: List, val pillowImageSmall: String, val pillowImageLarge: String, ) @@ -136,7 +139,7 @@ fun CrossSellFloatingBottomSheet( dragHandle = { CrossSellDragHandle( text = state.data?.recommendedCrossSell?.bannerText - ?: state.data?.recommendedAddon?.let { stringResource(Res.string.CROSS_SELL_BANNER_TEXT) }, + ?: state.data?.recommendedAddon?.let { it.banner ?: stringResource(Res.string.CROSS_SELL_BANNER_TEXT) }, modifier = Modifier .padding(horizontal = 16.dp) .clip(HedvigTheme.shapes.cornerXLargeTop), @@ -174,6 +177,7 @@ fun CrossSellBottomSheet( CrossSellDragHandle( contentPadding = PaddingValues(horizontal = 16.dp), text = state.data?.recommendedCrossSell?.bannerText + ?: state.data?.recommendedAddon?.banner ?: stringResource(Res.string.CROSS_SELL_BANNER_TEXT), ) } @@ -405,6 +409,27 @@ private fun AddonRecommendationSection( modifier = Modifier.padding(horizontal = 16.dp), textAlign = TextAlign.Center, ) + if (recommendedAddon.benefits.isNotEmpty()) { + Spacer(Modifier.height(32.dp)) + Column( + verticalArrangement = Arrangement.spacedBy(10.dp), + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 24.dp), + ) { + for (benefit in recommendedAddon.benefits) { + Row(verticalAlignment = Alignment.Top) { + Icon( + imageVector = HedvigIcons.Checkmark, + contentDescription = EmptyContentDescription, + modifier = Modifier.size(24.dp), + ) + Spacer(Modifier.width(12.dp)) + HedvigText(benefit) + } + } + } + } Spacer(Modifier.height(48.dp)) HedvigButton( text = recommendedAddon.buttonTitle, @@ -1059,6 +1084,12 @@ private fun PreviewRecommendedAddon( buttonTitle = "Check the addon", description = "Best addon in the world", deepLink = "deep", + banner = "Add extra safety when traveling", + benefits = listOf( + "Travel up to 60 days in a row", + "Delayed bags and flights covered", + "Applies to your whole household", + ), pillowImageSmall = "src", pillowImageLarge = "src", ), From 74dde9d5667827c87192fb21d86b582036297a48 Mon Sep 17 00:00:00 2001 From: stylianosgakis Date: Tue, 7 Jul 2026 16:25:31 +0200 Subject: [PATCH 2/2] Fix spacings when benefits are also rendering --- .../src/main/kotlin/com/hedvig/android/crosssells/CrossSells.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/ui/cross-sells/src/main/kotlin/com/hedvig/android/crosssells/CrossSells.kt b/app/ui/cross-sells/src/main/kotlin/com/hedvig/android/crosssells/CrossSells.kt index 38bee6ef9c..f646a4368b 100644 --- a/app/ui/cross-sells/src/main/kotlin/com/hedvig/android/crosssells/CrossSells.kt +++ b/app/ui/cross-sells/src/main/kotlin/com/hedvig/android/crosssells/CrossSells.kt @@ -430,7 +430,7 @@ private fun AddonRecommendationSection( } } } - Spacer(Modifier.height(48.dp)) + Spacer(Modifier.height(if (recommendedAddon.benefits.isEmpty()) 48.dp else 32.dp)) HedvigButton( text = recommendedAddon.buttonTitle, onClick = {