diff --git a/app/feature/feature-movingflow/build.gradle.kts b/app/feature/feature-movingflow/build.gradle.kts
index 0f8b5b01a7..98f81438c0 100644
--- a/app/feature/feature-movingflow/build.gradle.kts
+++ b/app/feature/feature-movingflow/build.gradle.kts
@@ -28,6 +28,7 @@ dependencies {
implementation(projects.coreUiData)
implementation(projects.dataContractAndroid)
implementation(projects.dataProductVariantAndroid)
+ implementation(projects.uiTiersAndAddons)
implementation(projects.dataProductVariantPublic)
implementation(projects.designSystemHedvig)
implementation(projects.moleculeAndroid)
diff --git a/app/feature/feature-movingflow/src/main/kotlin/com/hedvig/android/feature/movingflow/ui/summary/SummaryDestination.kt b/app/feature/feature-movingflow/src/main/kotlin/com/hedvig/android/feature/movingflow/ui/summary/SummaryDestination.kt
index dc5bfa210b..47475d4167 100644
--- a/app/feature/feature-movingflow/src/main/kotlin/com/hedvig/android/feature/movingflow/ui/summary/SummaryDestination.kt
+++ b/app/feature/feature-movingflow/src/main/kotlin/com/hedvig/android/feature/movingflow/ui/summary/SummaryDestination.kt
@@ -1,20 +1,12 @@
package com.hedvig.android.feature.movingflow.ui.summary
-import androidx.compose.animation.AnimatedVisibility
-import androidx.compose.animation.expandVertically
-import androidx.compose.animation.shrinkVertically
-import androidx.compose.foundation.Image
-import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.size
-import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
@@ -27,9 +19,6 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.clip
-import androidx.compose.ui.platform.LocalUriHandler
-import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
@@ -39,7 +28,6 @@ import com.hedvig.android.core.uidata.UiCurrencyCode.SEK
import com.hedvig.android.core.uidata.UiMoney
import com.hedvig.android.data.contract.ContractGroup
import com.hedvig.android.data.contract.ContractType
-import com.hedvig.android.data.contract.android.toPillow
import com.hedvig.android.data.productvariant.InsurableLimit
import com.hedvig.android.data.productvariant.InsurableLimit.InsurableLimitType.BIKE
import com.hedvig.android.data.productvariant.InsuranceVariantDocument
@@ -48,12 +36,9 @@ import com.hedvig.android.data.productvariant.ProductVariant
import com.hedvig.android.data.productvariant.ProductVariantPeril
import com.hedvig.android.design.system.hedvig.AccordionData
import com.hedvig.android.design.system.hedvig.AccordionList
-import com.hedvig.android.design.system.hedvig.ButtonDefaults.ButtonSize.Medium
import com.hedvig.android.design.system.hedvig.ButtonDefaults.ButtonSize.Small
-import com.hedvig.android.design.system.hedvig.ButtonDefaults.ButtonStyle.Secondary
import com.hedvig.android.design.system.hedvig.HedvigAlertDialog
import com.hedvig.android.design.system.hedvig.HedvigButton
-import com.hedvig.android.design.system.hedvig.HedvigCard
import com.hedvig.android.design.system.hedvig.HedvigDialogError
import com.hedvig.android.design.system.hedvig.HedvigErrorSection
import com.hedvig.android.design.system.hedvig.HedvigFullScreenCenterAlignedProgress
@@ -62,16 +47,11 @@ import com.hedvig.android.design.system.hedvig.HedvigPreview
import com.hedvig.android.design.system.hedvig.HedvigScaffold
import com.hedvig.android.design.system.hedvig.HedvigText
import com.hedvig.android.design.system.hedvig.HedvigTheme
-import com.hedvig.android.design.system.hedvig.HorizontalDivider
import com.hedvig.android.design.system.hedvig.HorizontalItemsWithMaximumSpaceTaken
-import com.hedvig.android.design.system.hedvig.Icon
import com.hedvig.android.design.system.hedvig.NotificationDefaults.NotificationPriority.Info
import com.hedvig.android.design.system.hedvig.Surface
import com.hedvig.android.design.system.hedvig.datepicker.HedvigDateTimeFormatterDefaults
import com.hedvig.android.design.system.hedvig.datepicker.getLocale
-import com.hedvig.android.design.system.hedvig.icon.ArrowNorthEast
-import com.hedvig.android.design.system.hedvig.icon.HedvigIcons
-import com.hedvig.android.design.system.hedvig.ripple
import com.hedvig.android.feature.movingflow.data.MovingFlowQuotes
import com.hedvig.android.feature.movingflow.data.MovingFlowQuotes.DisplayItem
import com.hedvig.android.feature.movingflow.data.MovingFlowQuotes.MoveHomeQuote
@@ -81,6 +61,8 @@ import com.hedvig.android.feature.movingflow.ui.summary.SummaryUiState.Content
import com.hedvig.android.feature.movingflow.ui.summary.SummaryUiState.Content.SubmitError.Generic
import com.hedvig.android.feature.movingflow.ui.summary.SummaryUiState.Content.SubmitError.WithMessage
import com.hedvig.android.feature.movingflow.ui.summary.SummaryUiState.Loading
+import com.hedvig.android.tiersandaddons.QuoteCard
+import com.hedvig.android.tiersandaddons.QuoteDisplayItem
import hedvig.resources.R
import kotlinx.datetime.LocalDate
import kotlinx.datetime.toJavaLocalDate
@@ -239,144 +221,25 @@ private fun SummaryScreen(
@Composable
private fun QuoteCard(quote: MovingFlowQuotes.Quote, modifier: Modifier = Modifier) {
- var showDetails by rememberSaveable { mutableStateOf(false) }
- HedvigCard(
- modifier = modifier,
- onClick = { showDetails = !showDetails },
- interactionSource = null,
- indication = ripple(bounded = true, radius = 1000.dp),
- ) {
- Column(modifier = Modifier.padding(16.dp)) {
- Row {
- Image(
- painter = painterResource(quote.productVariant.contractGroup.toPillow()),
- contentDescription = null,
- modifier = Modifier.size(48.dp),
- )
- Spacer(modifier = Modifier.width(12.dp))
- Column {
- HedvigText(
- text = quote.productVariant.displayName,
- )
- val locale = getLocale()
- val startDate = remember(quote.startDate) {
- HedvigDateTimeFormatterDefaults.dateMonthAndYear(locale).format(quote.startDate.toJavaLocalDate())
- }
- HedvigText(
- text = stringResource(R.string.CHANGE_ADDRESS_ACTIVATION_DATE, startDate),
- color = HedvigTheme.colorScheme.textSecondary,
- )
- }
- }
- Spacer(Modifier.height(16.dp))
- HorizontalItemsWithMaximumSpaceTaken(
- startSlot = {
- HedvigText(stringResource(R.string.TIER_FLOW_TOTAL))
- },
- endSlot = {
- HedvigText(
- text = stringResource(
- R.string.OFFER_COST_AND_PREMIUM_PERIOD_ABBREVIATION,
- quote.premium.toString(),
- ),
- textAlign = TextAlign.End,
- modifier = Modifier.wrapContentWidth(Alignment.End),
- )
- },
- )
- AnimatedVisibility(
- visible = showDetails,
- enter = expandVertically(expandFrom = Alignment.Top),
- exit = shrinkVertically(shrinkTowards = Alignment.Top),
- ) {
- Column {
- Spacer(Modifier.height(16.dp))
- Column(verticalArrangement = Arrangement.spacedBy(16.dp)) {
- HorizontalDivider()
- if (quote.displayItems.isNotEmpty()) {
- Column {
- HedvigText(stringResource(R.string.TIER_FLOW_SUMMARY_OVERVIEW_SUBTITLE))
- for (displayItem in quote.displayItems) {
- InfoRow(displayItem.title, displayItem.value)
- }
- }
- }
- if (quote.productVariant.insurableLimits.isNotEmpty()) {
- Column {
- HedvigText(stringResource(R.string.TIER_FLOW_SUMMARY_COVERAGE_SUBTITLE))
- for (insurableLimit in quote.productVariant.insurableLimits) {
- InfoRow(
- insurableLimit.label,
- insurableLimit.limit,
- )
- }
- }
- }
- if (quote.productVariant.documents.isNotEmpty()) {
- Column {
- HedvigText(stringResource(R.string.TIER_FLOW_SUMMARY_DOCUMENTS_SUBTITLE))
- for (document in quote.productVariant.documents) {
- val uriHandler = LocalUriHandler.current
- Row(
- modifier = Modifier
- .fillMaxWidth()
- .clip(HedvigTheme.shapes.cornerExtraSmall)
- .clickable {
- uriHandler.openUri(document.url)
- },
- ) {
- HedvigText(
- text = document.displayName,
- color = HedvigTheme.colorScheme.textSecondary,
- modifier = Modifier.weight(1f),
- )
- Spacer(Modifier.width(8.dp))
- Icon(
- imageVector = HedvigIcons.ArrowNorthEast,
- contentDescription = null,
- tint = HedvigTheme.colorScheme.fillPrimary,
- modifier = Modifier.wrapContentWidth(),
- )
- }
- }
- }
- }
- }
- }
- }
- Spacer(Modifier.height(16.dp))
- HedvigButton(
- text = if (showDetails) {
- stringResource(R.string.TIER_FLOW_SUMMARY_HIDE_DETAILS_BUTTON)
- } else {
- stringResource(R.string.TIER_FLOW_SUMMARY_SHOW_DETAILS)
- },
- onClick = { showDetails = !showDetails },
- enabled = true,
- buttonStyle = Secondary,
- buttonSize = Medium,
- modifier = Modifier.fillMaxWidth(),
- )
- }
+ val locale = getLocale()
+ val startDate = remember(quote.startDate) {
+ HedvigDateTimeFormatterDefaults.dateMonthAndYear(
+ locale,
+ ).format(quote.startDate.toJavaLocalDate())
}
-}
-
-@Composable
-private fun InfoRow(leftText: String, rightText: String, modifier: Modifier = Modifier) {
- HorizontalItemsWithMaximumSpaceTaken(
- startSlot = {
- HedvigText(leftText, color = HedvigTheme.colorScheme.textSecondary)
- },
- endSlot = {
- HedvigText(
- text = rightText,
- color = HedvigTheme.colorScheme.textSecondary,
- textAlign = TextAlign.End,
- modifier = Modifier.wrapContentWidth(Alignment.End),
+ val subtitle = stringResource(R.string.CHANGE_ADDRESS_ACTIVATION_DATE, startDate)
+ QuoteCard(
+ productVariant = quote.productVariant,
+ subtitle = subtitle,
+ premium = quote.premium.toString(),
+ displayItems = quote.displayItems.map {
+ QuoteDisplayItem(
+ title = it.title,
+ subtitle = it.subtitle,
+ value = it.value,
)
},
modifier = modifier,
- spaceBetween = 8.dp,
)
}
diff --git a/app/ui/ui-tiers-and-addons/build.gradle.kts b/app/ui/ui-tiers-and-addons/build.gradle.kts
new file mode 100644
index 0000000000..67df7e75a6
--- /dev/null
+++ b/app/ui/ui-tiers-and-addons/build.gradle.kts
@@ -0,0 +1,15 @@
+plugins {
+ id("hedvig.android.ktlint")
+ id("hedvig.android.library")
+ id("hedvig.android.library.compose")
+ alias(libs.plugins.dependencyAnalysis)
+ alias(libs.plugins.squareSortDependencies)
+}
+
+dependencies {
+ implementation(projects.composeUi)
+ implementation(projects.coreResources)
+ implementation(projects.dataContractAndroid)
+ implementation(projects.dataProductVariantPublic)
+ implementation(projects.designSystemHedvig)
+}
diff --git a/app/ui/ui-tiers-and-addons/src/main/AndroidManifest.xml b/app/ui/ui-tiers-and-addons/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000..568741e54f
--- /dev/null
+++ b/app/ui/ui-tiers-and-addons/src/main/AndroidManifest.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/app/ui/ui-tiers-and-addons/src/main/kotlin/com/hedvig/android/tiersandaddons/QuoteDisplayItem.kt b/app/ui/ui-tiers-and-addons/src/main/kotlin/com/hedvig/android/tiersandaddons/QuoteDisplayItem.kt
new file mode 100644
index 0000000000..d80aeb6e82
--- /dev/null
+++ b/app/ui/ui-tiers-and-addons/src/main/kotlin/com/hedvig/android/tiersandaddons/QuoteDisplayItem.kt
@@ -0,0 +1,258 @@
+package com.hedvig.android.tiersandaddons
+
+import androidx.compose.animation.AnimatedVisibility
+import androidx.compose.animation.expandVertically
+import androidx.compose.animation.shrinkVertically
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.layout.wrapContentWidth
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.platform.LocalUriHandler
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.tooling.preview.PreviewParameter
+import androidx.compose.ui.unit.dp
+import com.hedvig.android.compose.ui.preview.BooleanCollectionPreviewParameterProvider
+import com.hedvig.android.data.contract.ContractGroup.DOG
+import com.hedvig.android.data.contract.ContractType.SE_HOUSE
+import com.hedvig.android.data.contract.android.toPillow
+import com.hedvig.android.data.productvariant.ProductVariant
+import com.hedvig.android.design.system.hedvig.ButtonDefaults.ButtonSize.Medium
+import com.hedvig.android.design.system.hedvig.ButtonDefaults.ButtonStyle.Secondary
+import com.hedvig.android.design.system.hedvig.HedvigButton
+import com.hedvig.android.design.system.hedvig.HedvigCard
+import com.hedvig.android.design.system.hedvig.HedvigPreview
+import com.hedvig.android.design.system.hedvig.HedvigText
+import com.hedvig.android.design.system.hedvig.HedvigTheme
+import com.hedvig.android.design.system.hedvig.HorizontalDivider
+import com.hedvig.android.design.system.hedvig.HorizontalItemsWithMaximumSpaceTaken
+import com.hedvig.android.design.system.hedvig.Icon
+import com.hedvig.android.design.system.hedvig.Surface
+import com.hedvig.android.design.system.hedvig.icon.ArrowNorthEast
+import com.hedvig.android.design.system.hedvig.icon.HedvigIcons
+import com.hedvig.android.design.system.hedvig.ripple
+import hedvig.resources.R
+
+data class QuoteDisplayItem(
+ val title: String,
+ val subtitle: String?,
+ val value: String,
+)
+
+@Composable
+fun QuoteCard(
+ productVariant: ProductVariant,
+ subtitle: String,
+ premium: String,
+ displayItems: List,
+ modifier: Modifier = Modifier,
+) {
+ var showDetails by rememberSaveable { mutableStateOf(false) }
+ QuoteCard(
+ showDetails = showDetails,
+ setShowDetails = { showDetails = it },
+ productVariant = productVariant,
+ subtitle = subtitle,
+ premium = premium,
+ displayItems = displayItems,
+ modifier = modifier,
+ )
+}
+
+@Composable
+private fun QuoteCard(
+ showDetails: Boolean,
+ setShowDetails: (Boolean) -> Unit,
+ productVariant: ProductVariant,
+ subtitle: String,
+ premium: String,
+ displayItems: List,
+ modifier: Modifier = Modifier,
+) {
+ HedvigCard(
+ modifier = modifier,
+ onClick = { setShowDetails(!showDetails) },
+ interactionSource = null,
+ indication = ripple(bounded = true, radius = 1000.dp),
+ ) {
+ Column(modifier = Modifier.padding(16.dp)) {
+ Row {
+ Image(
+ painter = painterResource(productVariant.contractGroup.toPillow()),
+ contentDescription = null,
+ modifier = Modifier.size(48.dp),
+ )
+ Spacer(modifier = Modifier.width(12.dp))
+ Column {
+ HedvigText(
+ text = productVariant.displayName,
+ )
+ HedvigText(
+ text = subtitle,
+ color = HedvigTheme.colorScheme.textSecondary,
+ )
+ }
+ }
+ Spacer(Modifier.height(16.dp))
+ HorizontalItemsWithMaximumSpaceTaken(
+ startSlot = {
+ HedvigText(stringResource(R.string.TIER_FLOW_TOTAL))
+ },
+ endSlot = {
+ HedvigText(
+ text = stringResource(
+ R.string.OFFER_COST_AND_PREMIUM_PERIOD_ABBREVIATION,
+ premium,
+ ),
+ textAlign = TextAlign.End,
+ modifier = Modifier.wrapContentWidth(Alignment.End),
+ )
+ },
+ )
+ AnimatedVisibility(
+ visible = showDetails,
+ enter = expandVertically(expandFrom = Alignment.Top),
+ exit = shrinkVertically(shrinkTowards = Alignment.Top),
+ ) {
+ Column {
+ Spacer(Modifier.height(16.dp))
+ Column(verticalArrangement = Arrangement.spacedBy(16.dp)) {
+ HorizontalDivider()
+ if (displayItems.isNotEmpty()) {
+ Column {
+ HedvigText(stringResource(R.string.TIER_FLOW_SUMMARY_OVERVIEW_SUBTITLE))
+ for (displayItem in displayItems) {
+ InfoRow(displayItem.title, displayItem.value)
+ }
+ }
+ }
+ if (productVariant.insurableLimits.isNotEmpty()) {
+ Column {
+ HedvigText(stringResource(R.string.TIER_FLOW_SUMMARY_COVERAGE_SUBTITLE))
+ for (insurableLimit in productVariant.insurableLimits) {
+ InfoRow(
+ insurableLimit.label,
+ insurableLimit.limit,
+ )
+ }
+ }
+ }
+ if (productVariant.documents.isNotEmpty()) {
+ Column {
+ HedvigText(stringResource(R.string.TIER_FLOW_SUMMARY_DOCUMENTS_SUBTITLE))
+ for (document in productVariant.documents) {
+ val uriHandler = LocalUriHandler.current
+ Row(
+ modifier = Modifier
+ .fillMaxWidth()
+ .clip(HedvigTheme.shapes.cornerExtraSmall)
+ .clickable {
+ uriHandler.openUri(document.url)
+ },
+ ) {
+ HedvigText(
+ text = document.displayName,
+ color = HedvigTheme.colorScheme.textSecondary,
+ modifier = Modifier.weight(1f),
+ )
+ Spacer(Modifier.width(8.dp))
+ Icon(
+ imageVector = HedvigIcons.ArrowNorthEast,
+ contentDescription = null,
+ tint = HedvigTheme.colorScheme.fillPrimary,
+ modifier = Modifier.wrapContentWidth(),
+ )
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ Spacer(Modifier.height(16.dp))
+ HedvigButton(
+ text = if (showDetails) {
+ stringResource(R.string.TIER_FLOW_SUMMARY_HIDE_DETAILS_BUTTON)
+ } else {
+ stringResource(R.string.TIER_FLOW_SUMMARY_SHOW_DETAILS)
+ },
+ onClick = { setShowDetails(!showDetails) },
+ enabled = true,
+ buttonStyle = Secondary,
+ buttonSize = Medium,
+ modifier = Modifier.fillMaxWidth(),
+ )
+ }
+ }
+}
+
+@Composable
+private fun InfoRow(leftText: String, rightText: String, modifier: Modifier = Modifier) {
+ HorizontalItemsWithMaximumSpaceTaken(
+ startSlot = {
+ HedvigText(leftText, color = HedvigTheme.colorScheme.textSecondary)
+ },
+ endSlot = {
+ HedvigText(
+ text = rightText,
+ color = HedvigTheme.colorScheme.textSecondary,
+ textAlign = TextAlign.End,
+ modifier = Modifier.wrapContentWidth(Alignment.End),
+ )
+ },
+ modifier = modifier,
+ spaceBetween = 8.dp,
+ )
+}
+
+@HedvigPreview
+@Composable
+private fun PreviewQuoteCard(
+ @PreviewParameter(BooleanCollectionPreviewParameterProvider::class) showDetails: Boolean,
+) {
+ HedvigTheme {
+ Surface(color = HedvigTheme.colorScheme.backgroundPrimary) {
+ QuoteCard(
+ showDetails = showDetails,
+ setShowDetails = {},
+ productVariant = ProductVariant(
+ displayName = "displayName",
+ contractGroup = DOG,
+ contractType = SE_HOUSE,
+ partner = "partner",
+ perils = emptyList(),
+ insurableLimits = emptyList(),
+ documents = emptyList(),
+ displayTierName = "displayTierName",
+ tierDescription = "tierDescription",
+ ),
+ subtitle = "subtitle",
+ premium = "premium",
+ displayItems = List(5) {
+ QuoteDisplayItem(
+ title = "title$it",
+ subtitle = "subtitle$it",
+ value = "value$it",
+ )
+ },
+ )
+ }
+ }
+}
diff --git a/hedvig-lint/lint-baseline/lint-baseline-ui-tiers-and-addons.xml b/hedvig-lint/lint-baseline/lint-baseline-ui-tiers-and-addons.xml
new file mode 100644
index 0000000000..1e318ef396
--- /dev/null
+++ b/hedvig-lint/lint-baseline/lint-baseline-ui-tiers-and-addons.xml
@@ -0,0 +1,4 @@
+
+
+
+