diff --git a/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/RewardCarouselScreen.kt b/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/RewardCarouselScreen.kt index c3d6c60f7..9e8643b02 100644 --- a/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/RewardCarouselScreen.kt +++ b/app/src/main/java/com/kickstarter/ui/activities/compose/projectpage/RewardCarouselScreen.kt @@ -377,7 +377,8 @@ fun RewardCarouselScreen( } else null, addonsPillVisible = reward.hasAddons(), isCTAButtonVisible = project.isAllowedToPledge(), - isSecret = reward.isSecretReward() == true + isSecret = reward.isSecretReward() == true, + isFeatured = reward.isFeatured() == true ) } } diff --git a/app/src/main/java/com/kickstarter/ui/compose/KSRewardCard.kt b/app/src/main/java/com/kickstarter/ui/compose/KSRewardCard.kt index 03deba5b0..29baae406 100644 --- a/app/src/main/java/com/kickstarter/ui/compose/KSRewardCard.kt +++ b/app/src/main/java/com/kickstarter/ui/compose/KSRewardCard.kt @@ -20,16 +20,19 @@ import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex import com.kickstarter.R import com.kickstarter.models.Photo +import com.kickstarter.ui.compose.designsystem.KSFeaturedRewardBadge import com.kickstarter.ui.compose.designsystem.KSGreenBadge import com.kickstarter.ui.compose.designsystem.KSPrimaryGreenButton import com.kickstarter.ui.compose.designsystem.KSSecretRewardBadge @@ -94,6 +97,35 @@ fun KSRewardCardPreviewImageSelectedSecret() { } } +@Composable +@Preview(name = "Light", uiMode = Configuration.UI_MODE_NIGHT_NO) +@Preview(name = "Dark", uiMode = Configuration.UI_MODE_NIGHT_YES) +fun KSRewardCardPreviewImageSelectedFeatured() { + KSTheme { + KSRewardCard( + amount = "$20", + conversion = "about $400", + title = "Featured reward", + backerCountBadgeText = "23 backers", + image = Photo.builder().altText("").full("").build(), + description = "this is a description", + isCTAButtonEnabled = true, + isSecret = false, + isFeatured = true, + estimatedDelivery = "June 10th, 2026", + includes = listOf("1 Comic Book", "2 pins", "3 happy meals"), + yourSelectionIsVisible = true, + ctaButtonText = "Select", + expirationDateText = "4 Days", + shippingSummaryText = "Anywhere", + addonsPillVisible = true, + remainingText = "5 left", + estimatedShippingCost = "About $10-$15", + onRewardSelectClicked = { } + ) + } +} + @Composable @Preview(name = "Light", uiMode = Configuration.UI_MODE_NIGHT_NO) @Preview(name = "Dark", uiMode = Configuration.UI_MODE_NIGHT_YES) @@ -122,6 +154,35 @@ fun KSRewardCardPreviewImageNoSelectedSecret() { } } +@Composable +@Preview(name = "Light", uiMode = Configuration.UI_MODE_NIGHT_NO) +@Preview(name = "Dark", uiMode = Configuration.UI_MODE_NIGHT_YES) +fun KSRewardCardPreviewImageNoSelectedFeatured() { + KSTheme { + KSRewardCard( + amount = "$20", + conversion = "about $400", + title = "Featured reward", + backerCountBadgeText = "23 backers", + image = Photo.builder().altText("").full("").build(), + description = "this is a description", + isCTAButtonEnabled = true, + isSecret = false, + isFeatured = true, + estimatedDelivery = "June 10th, 2026", + includes = listOf("1 Comic Book", "2 pins", "3 happy meals"), + yourSelectionIsVisible = false, + ctaButtonText = "Select", + expirationDateText = "4 Days", + shippingSummaryText = "Anywhere", + addonsPillVisible = true, + remainingText = "5 left", + estimatedShippingCost = "About $10-$15", + onRewardSelectClicked = { } + ) + } +} + @Composable @Preview(name = "Light", uiMode = Configuration.UI_MODE_NIGHT_NO) @Preview(name = "Dark", uiMode = Configuration.UI_MODE_NIGHT_YES) @@ -177,6 +238,34 @@ fun KSRewardCardPreviewNoImageSelectedSecret() { } } +@Composable +@Preview(name = "Light", uiMode = Configuration.UI_MODE_NIGHT_NO) +@Preview(name = "Dark", uiMode = Configuration.UI_MODE_NIGHT_YES) +fun KSRewardCardPreviewNoImageSelectedFeatured() { + KSTheme { + KSRewardCard( + amount = "$20", + conversion = "about $400", + title = "Featured reward", + backerCountBadgeText = "23 backers", + description = "this is a description", + isCTAButtonEnabled = true, + isSecret = false, + isFeatured = true, + estimatedDelivery = "June 10th, 2026", + includes = listOf("1 Comic Book", "2 pins", "3 happy meals"), + yourSelectionIsVisible = true, + ctaButtonText = "Select", + expirationDateText = "4 Days", + shippingSummaryText = "Anywhere", + addonsPillVisible = true, + remainingText = "5 left", + estimatedShippingCost = "About $10-$15", + onRewardSelectClicked = { } + ) + } +} + @Composable @Preview(name = "Light", uiMode = Configuration.UI_MODE_NIGHT_NO) @Preview(name = "Dark", uiMode = Configuration.UI_MODE_NIGHT_YES) @@ -237,6 +326,40 @@ fun KSRewardCardPreviewNoImageNoSelectedSecret() { } } +@Composable +@Preview(name = "Light", uiMode = Configuration.UI_MODE_NIGHT_NO) +@Preview(name = "Dark", uiMode = Configuration.UI_MODE_NIGHT_YES) +fun KSRewardCardPreviewNoImageNoSelectedFeatured() { + KSTheme { + Box( + modifier = Modifier + .width(KSTheme.dimensions.cardWidth) + .padding(KSTheme.dimensions.paddingMediumLarge) + ) { + KSRewardCard( + amount = "$20", + conversion = "about $400", + title = "Featured reward", + backerCountBadgeText = "23 backers", + description = "this is a description", + isCTAButtonEnabled = true, + isSecret = false, + isFeatured = true, + estimatedDelivery = "June 10th, 2026", + includes = listOf("1 Comic Book", "2 pins", "3 happy meals"), + yourSelectionIsVisible = false, + ctaButtonText = "Select", + expirationDateText = "4 Days", + shippingSummaryText = "Anywhere", + addonsPillVisible = true, + remainingText = "5 left", + estimatedShippingCost = "About $10-$15", + onRewardSelectClicked = { } + ) + } + } +} + @Composable @Preview(name = "Light", uiMode = Configuration.UI_MODE_NIGHT_NO) @Preview(name = "Dark", uiMode = Configuration.UI_MODE_NIGHT_YES) @@ -288,27 +411,41 @@ fun KSRewardCard( estimatedShippingCost: String? = null, onRewardSelectClicked: () -> Unit, isSecret: Boolean = false, + isFeatured: Boolean = false, ) { Box(modifier = modifier.width(KSTheme.dimensions.cardWidth)) { - if (isSecret && image == null && !yourSelectionIsVisible) { + if ((isSecret || isFeatured) && image == null && !yourSelectionIsVisible) { Box( modifier = Modifier .offset(x = dimensions.paddingMedium, y = -(dimensions.secretRewardBadgeOffsetY)) .zIndex(1f) ) { - KSSecretRewardBadge() + Row( + horizontalArrangement = Arrangement.spacedBy(dimensions.paddingSmall), + verticalAlignment = Alignment.CenterVertically + ) { + if (isSecret) KSSecretRewardBadge() + if (isFeatured) KSFeaturedRewardBadge() + } } } + val cardShape = RoundedCornerShape(KSTheme.dimensions.radiusMediumSmall) Card( modifier = Modifier.fillMaxWidth(), - shape = RoundedCornerShape(KSTheme.dimensions.radiusMediumSmall), + shape = cardShape, + colors = CardDefaults.cardColors(containerColor = KSTheme.colors.kds_white), + border = null, ) { - Column(modifier = Modifier.background(KSTheme.colors.kds_white)) { + Column( + modifier = Modifier + .clip(cardShape) + .background(KSTheme.colors.kds_white) + ) { Box { if (image != null) { KSRewardAsyncImage(image = image) - if (isSecret) { + if (isSecret || isFeatured) { Box( modifier = Modifier .align(Alignment.BottomStart) @@ -317,14 +454,20 @@ fun KSRewardCard( y = dimensions.secretRewardBadgeOffsetY ) ) { - KSSecretRewardBadge() + Row( + horizontalArrangement = Arrangement.spacedBy(dimensions.paddingSmall), + verticalAlignment = Alignment.CenterVertically + ) { + if (isSecret) KSSecretRewardBadge() + if (isFeatured) KSFeaturedRewardBadge() + } } } } if (yourSelectionIsVisible) { YourSelectionTag() - if (isSecret && image == null) { + if ((isSecret || isFeatured) && image == null) { Box( modifier = Modifier .align(Alignment.BottomStart) @@ -333,7 +476,13 @@ fun KSRewardCard( top = dimensions.paddingXXXLarge ) ) { - KSSecretRewardBadge() + Row( + horizontalArrangement = Arrangement.spacedBy(dimensions.paddingSmall), + verticalAlignment = Alignment.CenterVertically + ) { + if (isSecret) KSSecretRewardBadge() + if (isFeatured) KSFeaturedRewardBadge() + } } } } diff --git a/app/src/main/java/com/kickstarter/ui/viewholders/AddOnViewHolder.kt b/app/src/main/java/com/kickstarter/ui/viewholders/AddOnViewHolder.kt index 0ffc811f3..d11174c79 100644 --- a/app/src/main/java/com/kickstarter/ui/viewholders/AddOnViewHolder.kt +++ b/app/src/main/java/com/kickstarter/ui/viewholders/AddOnViewHolder.kt @@ -2,6 +2,12 @@ package com.kickstarter.ui.viewholders import android.util.Pair import android.view.View +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.wrapContentSize +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp import androidx.core.view.isGone import androidx.recyclerview.widget.LinearLayoutManager import coil.load @@ -14,6 +20,7 @@ import com.kickstarter.libs.utils.ViewUtils import com.kickstarter.libs.utils.extensions.addToDisposable import com.kickstarter.models.Reward import com.kickstarter.ui.adapters.RewardItemsAdapter +import com.kickstarter.ui.compose.designsystem.KSFeaturedRewardBadge import com.kickstarter.ui.compose.designsystem.KSSecretRewardBadge import com.kickstarter.ui.compose.designsystem.KSTheme import com.kickstarter.ui.data.ProjectData @@ -154,14 +161,22 @@ class AddOnViewHolder(private val binding: ItemAddOnBinding) : KSViewHolder(bind val badgeOverImage = binding.secretBadgeComposeOverImage val badgeAboveCard = binding.secretBadgeComposeAboveCard - if (reward.isSecretReward() == true) { + val showBadge = reward.isSecretReward() == true || reward.isFeatured() == true + if (showBadge) { if (hasImage) { badgeOverImage.visibility = View.VISIBLE badgeAboveCard.visibility = View.GONE badgeOverImage.setContent { KSTheme { - KSSecretRewardBadge() + Row( + modifier = Modifier.wrapContentSize(), + horizontalArrangement = Arrangement.spacedBy(4.dp), + verticalAlignment = Alignment.CenterVertically + ) { + if (reward.isSecretReward() == true) KSSecretRewardBadge() + if (reward.isFeatured() == true) KSFeaturedRewardBadge() + } } } } else { @@ -170,7 +185,14 @@ class AddOnViewHolder(private val binding: ItemAddOnBinding) : KSViewHolder(bind badgeAboveCard.setContent { KSTheme { - KSSecretRewardBadge() + Row( + modifier = Modifier.wrapContentSize(), + horizontalArrangement = Arrangement.spacedBy(4.dp), + verticalAlignment = Alignment.CenterVertically + ) { + if (reward.isSecretReward() == true) KSSecretRewardBadge() + if (reward.isFeatured() == true) KSFeaturedRewardBadge() + } } } }