Updated on 2026-08-14
This commit is contained in:
parent
a0e5656330
commit
d82dbdd1e6
12 changed files with 256 additions and 129 deletions
|
|
@ -59,6 +59,8 @@ internal class TangemPayDetailsStateFactory(
|
|||
|
||||
fun getLoadedState(status: PaymentAccountStatusValue.Loaded): TangemPayDetailsUM {
|
||||
val hasUnfrozenCard = status.cards.any { it.frozenState == TangemPayCardFrozenState.Unfrozen }
|
||||
val hasIssuingCard = status.cards.any { it.state == TangemPayCardState.Issuing }
|
||||
val isAddCardEnabled = status.error == null && !hasIssuingCard
|
||||
return TangemPayDetailsUM(
|
||||
topBarConfig = TangemPayDetailsTopBarConfig(
|
||||
onBackClick = onBack,
|
||||
|
|
@ -88,7 +90,7 @@ internal class TangemPayDetailsStateFactory(
|
|||
}
|
||||
.toImmutableList(),
|
||||
onAddCardClick = intents::onAddCardClick,
|
||||
isAddCardEnabled = status.error == null,
|
||||
isAddCardEnabled = isAddCardEnabled,
|
||||
),
|
||||
),
|
||||
isBalanceHidden = false,
|
||||
|
|
|
|||
|
|
@ -141,6 +141,7 @@ internal fun TangemPayDetailsScreenV2(
|
|||
expressTransactionsBottomSheetState?.content(null)
|
||||
}
|
||||
|
||||
@Suppress("LongMethod")
|
||||
private fun LazyListScope.payDetailsBody(state: TangemPayDetailsUM) {
|
||||
item("balanceBlock") {
|
||||
BalanceBlock(
|
||||
|
|
@ -174,6 +175,15 @@ private fun LazyListScope.payDetailsBody(state: TangemPayDetailsUM) {
|
|||
modifier = Modifier.padding(horizontal = TangemTheme.dimens2.x4),
|
||||
title = resourceReference(R.string.tangempay_issuing_new_digital_card_title),
|
||||
subtitle = resourceReference(R.string.tangempay_reissue_card_in_progress_description),
|
||||
contentColor = TangemTheme.colors3.bg.opaque.secondary,
|
||||
leadingContent = {
|
||||
Icon(
|
||||
modifier = Modifier.size(20.dp),
|
||||
imageVector = ImageVector.vectorResource(R.drawable.ic_clock_24),
|
||||
contentDescription = null,
|
||||
tint = TangemTheme.colors3.icon.primary,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
package com.tangem.features.tangempay.ui
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
|
|
@ -11,7 +13,7 @@ import androidx.compose.ui.Alignment
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
|
|
@ -37,7 +39,6 @@ import com.tangem.core.ui.res.TangemTheme
|
|||
import com.tangem.core.ui.res.TangemThemePreviewRedesign
|
||||
import com.tangem.core.ui.res.generated.icons.Icons
|
||||
import com.tangem.core.ui.res.generated.icons.ic_card_plus_32
|
||||
import com.tangem.core.ui.res.generated.icons.ic_error_28
|
||||
import com.tangem.features.tangempay.details.impl.R
|
||||
import com.tangem.features.tangempay.entity.TangemPayIssueAdditionalCardUM
|
||||
|
||||
|
|
@ -72,47 +73,55 @@ internal fun TangemPayIssueAdditionalCardContent(state: TangemPayIssueAdditional
|
|||
|
||||
@Composable
|
||||
private fun Content(state: TangemPayIssueAdditionalCardUM) {
|
||||
val appearance = state.contentAppearance()
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
SpacerH(16.dp)
|
||||
StatusIcon(appearance = appearance)
|
||||
SpacerH(32.dp)
|
||||
CenteredMessageText(
|
||||
textRes = appearance.titleRes,
|
||||
style = TangemTheme.typography3.heading.small,
|
||||
color = TangemTheme.colors3.text.primary,
|
||||
)
|
||||
CenteredMessageText(
|
||||
textRes = appearance.subtitleRes,
|
||||
style = TangemTheme.typography3.subheading.medium,
|
||||
color = TangemTheme.colors3.text.secondary,
|
||||
)
|
||||
SpacerH(32.dp)
|
||||
FeeBlock(modifier = Modifier.padding(top = 16.dp), state = state)
|
||||
SpacerH(8.dp)
|
||||
BottomButtonsBlock(state = state, appearance = appearance)
|
||||
Column(modifier = Modifier.fillMaxWidth()) {
|
||||
Header()
|
||||
FeeBlock(state = state)
|
||||
if (state.isBalanceInsufficient) {
|
||||
InsufficientFundsNotification(state = state)
|
||||
}
|
||||
IssueButton(state = state)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun StatusIcon(appearance: IssueAdditionalCardContentAppearance) {
|
||||
private fun Header() {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
SpacerH(32.dp)
|
||||
StatusIcon()
|
||||
SpacerH(32.dp)
|
||||
CenteredMessageText(
|
||||
textRes = R.string.tangempay_issue_additional_card_title,
|
||||
style = TangemTheme.typography3.heading.small,
|
||||
color = TangemTheme.colors3.text.primary,
|
||||
)
|
||||
SpacerH(8.dp)
|
||||
CenteredMessageText(
|
||||
textRes = R.string.tangempay_issue_additional_card_description,
|
||||
style = TangemTheme.typography3.subheading.medium,
|
||||
color = TangemTheme.colors3.text.secondary,
|
||||
)
|
||||
SpacerH(32.dp)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun StatusIcon() {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(80.dp)
|
||||
.clip(CircleShape)
|
||||
.background(appearance.iconBackgroundColor),
|
||||
.background(TangemTheme.colors3.bg.status.infoSubtle),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
Icon(
|
||||
imageVector = appearance.icon,
|
||||
imageVector = Icons.ic_card_plus_32,
|
||||
contentDescription = null,
|
||||
tint = appearance.iconColor,
|
||||
tint = TangemTheme.colors3.icon.status.info,
|
||||
modifier = Modifier.size(28.dp),
|
||||
)
|
||||
}
|
||||
|
|
@ -152,68 +161,64 @@ private fun FeeBlock(state: TangemPayIssueAdditionalCardUM, modifier: Modifier =
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun BottomButtonsBlock(
|
||||
state: TangemPayIssueAdditionalCardUM,
|
||||
appearance: IssueAdditionalCardContentAppearance,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
private fun InsufficientFundsNotification(state: TangemPayIssueAdditionalCardUM, modifier: Modifier = Modifier) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = 16.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
.padding(start = 16.dp, end = 16.dp, top = 8.dp, bottom = 16.dp)
|
||||
.clip(RoundedCornerShape(16.dp))
|
||||
.background(TangemTheme.colors3.bg.status.warningSubtle)
|
||||
.padding(horizontal = 14.dp, vertical = 16.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
verticalAlignment = Alignment.Top,
|
||||
) {
|
||||
Image(
|
||||
modifier = Modifier.size(20.dp),
|
||||
painter = painterResource(R.drawable.img_usdc_16),
|
||||
contentDescription = null,
|
||||
)
|
||||
Column(
|
||||
modifier = Modifier.weight(1f),
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||
) {
|
||||
Text(
|
||||
text = stringResourceSafe(R.string.tangempay_reissue_card_insufficient_funds_title),
|
||||
style = TangemTheme.typography3.subheading.medium,
|
||||
color = TangemTheme.colors3.text.primary,
|
||||
)
|
||||
Text(
|
||||
text = stringResourceSafe(R.string.tangempay_reissue_card_insufficient_funds_subtitle),
|
||||
style = TangemTheme.typography3.caption.medium,
|
||||
color = TangemTheme.colors3.text.secondary,
|
||||
)
|
||||
}
|
||||
}
|
||||
TangemButton(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
variant = TangemButton.Variant.Secondary,
|
||||
size = TangemButton.Size.X12,
|
||||
onClick = state.onDismiss,
|
||||
text = resourceReference(R.string.common_cancel),
|
||||
)
|
||||
TangemButton(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
size = TangemButton.Size.X12,
|
||||
onClick = appearance.primaryAction(state),
|
||||
isEnabled = !state.isLoading,
|
||||
isLoading = state.isLoading,
|
||||
text = resourceReference(appearance.primaryButtonTextRes),
|
||||
size = TangemButton.Size.X8,
|
||||
onClick = state.onAddFundsClick,
|
||||
text = resourceReference(R.string.tangempay_card_details_add_funds),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private data class IssueAdditionalCardContentAppearance(
|
||||
val titleRes: Int,
|
||||
val subtitleRes: Int,
|
||||
val icon: ImageVector,
|
||||
val iconColor: Color,
|
||||
val iconBackgroundColor: Color,
|
||||
val primaryButtonTextRes: Int,
|
||||
val primaryAction: (TangemPayIssueAdditionalCardUM) -> () -> Unit,
|
||||
)
|
||||
|
||||
@Composable
|
||||
private fun TangemPayIssueAdditionalCardUM.contentAppearance(): IssueAdditionalCardContentAppearance {
|
||||
return if (isBalanceInsufficient) {
|
||||
IssueAdditionalCardContentAppearance(
|
||||
titleRes = R.string.tangempay_reissue_card_insufficient_funds_title,
|
||||
subtitleRes = R.string.tangempay_reissue_card_insufficient_funds_subtitle,
|
||||
icon = Icons.ic_error_28,
|
||||
iconColor = TangemTheme.colors3.icon.status.warning,
|
||||
iconBackgroundColor = TangemTheme.colors3.bg.status.warningSubtle,
|
||||
primaryButtonTextRes = R.string.tangempay_card_details_add_funds,
|
||||
primaryAction = { it.onAddFundsClick },
|
||||
)
|
||||
} else {
|
||||
IssueAdditionalCardContentAppearance(
|
||||
titleRes = R.string.tangempay_issue_additional_card_title,
|
||||
subtitleRes = R.string.tangempay_issue_additional_card_description,
|
||||
icon = Icons.ic_card_plus_32,
|
||||
iconColor = TangemTheme.colors3.icon.status.info,
|
||||
iconBackgroundColor = TangemTheme.colors3.bg.status.infoSubtle,
|
||||
primaryButtonTextRes = R.string.tangempay_issue_card,
|
||||
primaryAction = { it.onIssueClick },
|
||||
)
|
||||
}
|
||||
private fun IssueButton(state: TangemPayIssueAdditionalCardUM, modifier: Modifier = Modifier) {
|
||||
TangemButton(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp),
|
||||
size = TangemButton.Size.X12,
|
||||
onClick = state.onIssueClick,
|
||||
isEnabled = !state.isLoading && !state.isBalanceInsufficient,
|
||||
isLoading = state.isLoading,
|
||||
text = resourceReference(R.string.tangempay_issue_card),
|
||||
)
|
||||
}
|
||||
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
|
|
@ -223,29 +228,7 @@ private fun TangemPayIssueAdditionalCardContentPreview(
|
|||
@PreviewParameter(IssueAdditionalCardPreviewProvider::class) state: TangemPayIssueAdditionalCardUM,
|
||||
) {
|
||||
TangemThemePreviewRedesign {
|
||||
IssueAdditionalCardSheetPreview(state = state)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun IssueAdditionalCardSheetPreview(state: TangemPayIssueAdditionalCardUM) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.background(TangemTheme.colors3.bg.secondary),
|
||||
) {
|
||||
TangemTopBar(
|
||||
type = TangemTopBarType.BottomSheet,
|
||||
endContent = {
|
||||
TangemButton(
|
||||
iconStart = TangemIconUM.Icon(iconRes = R.drawable.ic_close_24),
|
||||
onClick = state.onDismiss,
|
||||
size = TangemButton.Size.X11,
|
||||
variant = TangemButton.Variant.Material,
|
||||
)
|
||||
},
|
||||
)
|
||||
Content(state)
|
||||
TangemPayIssueAdditionalCardContent(state = state)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue