diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/bottomsheets/TangemBottomSheet.kt b/core/ui/src/main/java/com/tangem/core/ui/components/bottomsheets/TangemBottomSheet.kt index 7627f60b0e..3f934a0f9b 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/bottomsheets/TangemBottomSheet.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/bottomsheets/TangemBottomSheet.kt @@ -21,7 +21,7 @@ import kotlinx.coroutines.launch @Composable inline fun TangemBottomSheet( config: TangemBottomSheetConfig, - contentColor: Color = TangemTheme.colors.background.primary, + containerColor: Color = TangemTheme.colors.background.primary, crossinline content: @Composable ColumnScope.(T) -> Unit, ) { var isVisible by remember { mutableStateOf(value = config.isShow) } @@ -31,9 +31,9 @@ inline fun TangemBottomSheet( ModalBottomSheet( onDismissRequest = config.onDismissRequest, sheetState = sheetState, - containerColor = contentColor, + containerColor = containerColor, shape = TangemTheme.shapes.bottomSheetLarge, - dragHandle = { TangemBottomSheetDraggableHeader(contentColor) }, + dragHandle = { TangemBottomSheetDraggableHeader(color = containerColor) }, ) { content(config.content) } diff --git a/features/manage-tokens/impl/src/main/java/com/tangem/managetokens/presentation/common/ui/ChooseWalletBottomSheet.kt b/features/manage-tokens/impl/src/main/java/com/tangem/managetokens/presentation/common/ui/ChooseWalletBottomSheet.kt index 610f54edc4..9bf85280d4 100644 --- a/features/manage-tokens/impl/src/main/java/com/tangem/managetokens/presentation/common/ui/ChooseWalletBottomSheet.kt +++ b/features/manage-tokens/impl/src/main/java/com/tangem/managetokens/presentation/common/ui/ChooseWalletBottomSheet.kt @@ -11,7 +11,7 @@ import com.tangem.managetokens.presentation.common.state.ChooseWalletState internal fun ChooseWalletBottomSheet(config: TangemBottomSheetConfig) { TangemBottomSheet( config = config, - contentColor = TangemTheme.colors.background.tertiary, + containerColor = TangemTheme.colors.background.tertiary, ) { ChooseWalletScreen(state = it.chooseWalletState) } diff --git a/features/manage-tokens/impl/src/main/java/com/tangem/managetokens/presentation/managetokens/ui/ChooseNetworkBottomSheet.kt b/features/manage-tokens/impl/src/main/java/com/tangem/managetokens/presentation/managetokens/ui/ChooseNetworkBottomSheet.kt index cd1809a96b..5cbdc20a93 100644 --- a/features/manage-tokens/impl/src/main/java/com/tangem/managetokens/presentation/managetokens/ui/ChooseNetworkBottomSheet.kt +++ b/features/manage-tokens/impl/src/main/java/com/tangem/managetokens/presentation/managetokens/ui/ChooseNetworkBottomSheet.kt @@ -12,7 +12,7 @@ import com.tangem.managetokens.presentation.managetokens.state.TokenItemState internal fun ChooseNetworkBottomSheet(config: TangemBottomSheetConfig) { TangemBottomSheet( config = config, - contentColor = TangemTheme.colors.background.tertiary, + containerColor = TangemTheme.colors.background.tertiary, ) { ChooseNetworkScreen(state = it.selectedToken, walletState = it.chooseWalletState) } diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/ChooseProviderBottomSheet.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/ChooseProviderBottomSheet.kt index 2dd33c473f..9f41e55e75 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/ChooseProviderBottomSheet.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/ui/ChooseProviderBottomSheet.kt @@ -25,7 +25,7 @@ import kotlinx.collections.immutable.toImmutableList fun ChooseProviderBottomSheet(config: TangemBottomSheetConfig) { TangemBottomSheet( config = config, - contentColor = TangemTheme.colors.background.tertiary, + containerColor = TangemTheme.colors.background.tertiary, ) { content: ChooseProviderBottomSheetConfig -> ChooseProviderBottomSheetContent(content = content) } diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/ui/components/exchange/ExchangeStatusBottomSheet.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/ui/components/exchange/ExchangeStatusBottomSheet.kt index f8850738e2..315d86a347 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/ui/components/exchange/ExchangeStatusBottomSheet.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/ui/components/exchange/ExchangeStatusBottomSheet.kt @@ -27,7 +27,7 @@ import com.tangem.feature.tokendetails.presentation.tokendetails.state.SwapTrans internal fun ExchangeStatusBottomSheet(config: TangemBottomSheetConfig) { TangemBottomSheet( config = config, - contentColor = TangemTheme.colors.background.tertiary, + containerColor = TangemTheme.colors.background.tertiary, ) { content: ExchangeStatusBottomSheetConfig -> ExchangeStatusBottomSheetContent(content = content) } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state2/model/BalancesAndLimitsBottomSheetConfig.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state2/model/BalancesAndLimitsBottomSheetConfig.kt new file mode 100644 index 0000000000..dc15fc27b1 --- /dev/null +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state2/model/BalancesAndLimitsBottomSheetConfig.kt @@ -0,0 +1,28 @@ +package com.tangem.feature.wallet.presentation.wallet.state2.model + +import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent + +internal data class BalancesAndLimitsBottomSheetConfig( + val currency: String, + val balance: Balance, + val limit: Limit, + val onBalanceInfoClick: () -> Unit, + val onLimitInfoClick: () -> Unit, +) : TangemBottomSheetConfigContent { + + data class Balance( + val totalBalance: String, + val availableBalance: String, + val blockedBalance: String, + val debit: String, + val pending: String, + val amlVerified: String, + ) + + data class Limit( + val availableBy: String, + val inStore: String, + val other: String, + val singleTransaction: String, + ) +} \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/WalletScreenV2.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/WalletScreenV2.kt index 47a88420e6..46380e8b44 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/WalletScreenV2.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/WalletScreenV2.kt @@ -29,16 +29,14 @@ import com.tangem.feature.wallet.impl.R import com.tangem.feature.wallet.presentation.wallet.state.ActionsBottomSheetConfig import com.tangem.feature.wallet.presentation.wallet.state.WalletAlertState import com.tangem.feature.wallet.presentation.wallet.state.components.WalletBottomSheetConfig -import com.tangem.feature.wallet.presentation.wallet.state2.model.NOT_INITIALIZED_WALLET_INDEX -import com.tangem.feature.wallet.presentation.wallet.state2.model.WalletScreenState -import com.tangem.feature.wallet.presentation.wallet.state2.model.WalletState -import com.tangem.feature.wallet.presentation.wallet.state2.model.WalletTokensListState +import com.tangem.feature.wallet.presentation.wallet.state2.model.* import com.tangem.feature.wallet.presentation.wallet.ui.components.TokenActionsBottomSheet import com.tangem.feature.wallet.presentation.wallet.ui.components.WalletsList import com.tangem.feature.wallet.presentation.wallet.ui.components.common.* import com.tangem.feature.wallet.presentation.wallet.ui.components.multicurrency.organizeTokensButton import com.tangem.feature.wallet.presentation.wallet.ui.components.singlecurrency.controlButtons import com.tangem.feature.wallet.presentation.wallet.ui.components.singlecurrency.marketPriceBlock +import com.tangem.feature.wallet.presentation.wallet.ui.components.visa.BalancesAndLimitsBottomSheet import com.tangem.feature.wallet.presentation.wallet.ui.components.visa.balancesAndLimitsBlock import com.tangem.feature.wallet.presentation.wallet.ui.components.visa.depositButton import com.tangem.feature.wallet.presentation.wallet.ui.utils.changeWalletAnimator @@ -172,6 +170,7 @@ private fun WalletContent( is TokenReceiveBottomSheetConfig -> TokenReceiveBottomSheet(config = bottomSheetConfig) is ActionsBottomSheetConfig -> TokenActionsBottomSheet(config = bottomSheetConfig) is ChooseAddressBottomSheetConfig -> ChooseAddressBottomSheet(config = bottomSheetConfig) + is BalancesAndLimitsBottomSheetConfig -> BalancesAndLimitsBottomSheet(config = bottomSheetConfig) } } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/visa/BalancesAndLimitsBottomSheet.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/visa/BalancesAndLimitsBottomSheet.kt new file mode 100644 index 0000000000..bd590c3ac4 --- /dev/null +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/visa/BalancesAndLimitsBottomSheet.kt @@ -0,0 +1,252 @@ +package com.tangem.feature.wallet.presentation.wallet.ui.components.visa + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider +import com.tangem.core.ui.components.SpacerH16 +import com.tangem.core.ui.components.SpacerWMax +import com.tangem.core.ui.components.bottomsheets.TangemBottomSheet +import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig +import com.tangem.core.ui.extensions.TextReference +import com.tangem.core.ui.extensions.resolveReference +import com.tangem.core.ui.extensions.stringReference +import com.tangem.core.ui.res.TangemTheme +import com.tangem.feature.wallet.impl.R +import com.tangem.feature.wallet.presentation.wallet.state2.model.BalancesAndLimitsBottomSheetConfig + +@Composable +internal fun BalancesAndLimitsBottomSheet(config: TangemBottomSheetConfig) { + TangemBottomSheet( + config = config, + containerColor = TangemTheme.colors.background.secondary, + ) { content: BalancesAndLimitsBottomSheetConfig -> + BalancesAndLimitsContent(content) + } +} + +@Composable +private fun BalancesAndLimitsContent(config: BalancesAndLimitsBottomSheetConfig, modifier: Modifier = Modifier) { + ContentContainer( + modifier = modifier, + title = { + Text( + text = "Balances & Limits", + style = TangemTheme.typography.subtitle1, + color = TangemTheme.colors.text.primary1, + ) + }, + firstBlock = { + BlockContent( + title = stringReference("Balance, ${config.currency}"), + content = { + BlockItem( + title = stringReference("Total"), + value = config.balance.totalBalance, + ) + BlockItem( + title = stringReference("AML Verified"), + value = config.balance.amlVerified, + ) + BlockItem( + title = stringReference("Available"), + value = config.balance.availableBalance, + ) + BlockItem( + title = stringReference("Blocked"), + value = config.balance.blockedBalance, + ) + BlockItem( + title = stringReference("Debit"), + value = config.balance.debit, + ) + BlockItem( + title = stringReference("Pending refund"), + value = config.balance.pending, + ) + }, + onInfoIconClick = config.onBalanceInfoClick, + ) + }, + secondBlock = { + BlockContent( + title = stringReference("Limits, ${config.currency}"), + description = stringReference("Available by ${config.limit.availableBy}"), + content = { + BlockItem( + title = stringReference("In-store (otp)"), + value = config.limit.inStore, + ) + BlockItem( + title = stringReference("Other (no-otp)"), + value = config.limit.other, + ) + BlockItem( + title = stringReference("Single transaction"), + value = config.limit.singleTransaction, + ) + }, + onInfoIconClick = config.onBalanceInfoClick, + ) + }, + ) +} + +@Composable +private inline fun BlockContent( + title: TextReference, + content: @Composable ColumnScope.() -> Unit, + noinline onInfoIconClick: () -> Unit, + modifier: Modifier = Modifier, + description: TextReference? = null, +) { + Column( + modifier = modifier + .padding(horizontal = TangemTheme.dimens.spacing16) + .fillMaxWidth() + .background( + color = TangemTheme.colors.background.primary, + shape = TangemTheme.shapes.roundedCornersXMedium, + ) + .padding(vertical = TangemTheme.dimens.spacing8), + ) { + Row( + modifier = Modifier + .padding( + start = TangemTheme.dimens.spacing12, + end = TangemTheme.dimens.spacing4, + ) + .fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + ) { + Text( + text = title.resolveReference(), + style = TangemTheme.typography.subtitle2, + color = TangemTheme.colors.text.tertiary, + ) + SpacerWMax() + if (description != null) { + Text( + text = description.resolveReference(), + style = TangemTheme.typography.body2, + color = TangemTheme.colors.text.tertiary, + ) + } + IconButton( + modifier = Modifier.size(TangemTheme.dimens.size32), + onClick = onInfoIconClick, + ) { + Icon( + modifier = Modifier.size(TangemTheme.dimens.size16), + painter = painterResource(id = R.drawable.ic_information_24), + tint = TangemTheme.colors.icon.informative, + contentDescription = null, + ) + } + } + content() + } +} + +@Composable +private fun BlockItem(title: TextReference, value: String, modifier: Modifier = Modifier) { + Row( + modifier = modifier + .padding(horizontal = TangemTheme.dimens.spacing12) + .fillMaxWidth() + .heightIn(min = TangemTheme.dimens.size32), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + ) { + Text( + text = title.resolveReference(), + style = TangemTheme.typography.caption2, + color = TangemTheme.colors.text.tertiary, + ) + Text( + text = value, + style = TangemTheme.typography.caption2, + color = TangemTheme.colors.text.primary1, + ) + } +} + +@Composable +private inline fun ContentContainer( + title: @Composable BoxScope.() -> Unit, + firstBlock: @Composable ColumnScope.() -> Unit, + secondBlock: @Composable ColumnScope.() -> Unit, + modifier: Modifier = Modifier, +) { + Column( + modifier = modifier.background(TangemTheme.colors.background.secondary), + verticalArrangement = Arrangement.spacedBy(space = TangemTheme.dimens.spacing12), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Box( + modifier = Modifier + .fillMaxWidth() + .heightIn(min = TangemTheme.dimens.size44), + contentAlignment = Alignment.Center, + content = title, + ) + firstBlock() + secondBlock() + SpacerH16() + } +} + +// region Preview +@Preview(showBackground = true, widthDp = 360) +@Composable +private fun BalancesAndLimitsBottomSheetPreview_Light( + @PreviewParameter(BalancesAndLimitsBottomSheetParameterProvider::class) state: BalancesAndLimitsBottomSheetConfig, +) { + TangemTheme { + BalancesAndLimitsContent(state) + } +} + +@Preview(showBackground = true, widthDp = 360) +@Composable +private fun BalancesAndLimitsBottomSheetPreview_Dark( + @PreviewParameter(BalancesAndLimitsBottomSheetParameterProvider::class) state: BalancesAndLimitsBottomSheetConfig, +) { + TangemTheme(isDark = true) { + BalancesAndLimitsContent(state) + } +} + +private class BalancesAndLimitsBottomSheetParameterProvider : + CollectionPreviewParameterProvider( + collection = listOf( + BalancesAndLimitsBottomSheetConfig( + currency = "USDT", + balance = BalancesAndLimitsBottomSheetConfig.Balance( + totalBalance = "492.45", + availableBalance = "392.45", + blockedBalance = "36.00", + debit = "00.00", + pending = "20.99", + amlVerified = "356.45", + ), + limit = BalancesAndLimitsBottomSheetConfig.Limit( + availableBy = "Nov, 11", + inStore = "563.00", + other = "100.00", + singleTransaction = "100.00", + ), + onBalanceInfoClick = {}, + onLimitInfoClick = {}, + ), + ), + ) +// endregion Preview \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/VisaWalletIntents.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/VisaWalletIntents.kt index f9860215e1..cc290a1099 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/VisaWalletIntents.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/VisaWalletIntents.kt @@ -10,6 +10,7 @@ import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.wallets.models.UserWalletId import com.tangem.feature.wallet.presentation.wallet.state.WalletEvent import com.tangem.feature.wallet.presentation.wallet.state2.WalletStateController +import com.tangem.feature.wallet.presentation.wallet.state2.model.BalancesAndLimitsBottomSheetConfig import com.tangem.feature.wallet.presentation.wallet.state2.utils.WalletEventSender import com.tangem.utils.coroutines.CoroutineDispatcherProvider import dagger.hilt.android.scopes.ViewModelScoped @@ -28,8 +29,8 @@ internal interface VisaWalletIntents { @ViewModelScoped internal class VisaWalletIntentsImplementor @Inject constructor( - private val eventSender: WalletEventSender, private val stateController: WalletStateController, + private val eventSender: WalletEventSender, private val getPrimaryCurrencyUseCase: GetPrimaryCurrencyStatusUpdatesUseCase, private val dispatchers: CoroutineDispatcherProvider, ) : BaseWalletClickIntents(), VisaWalletIntents { @@ -75,6 +76,35 @@ internal class VisaWalletIntentsImplementor @Inject constructor( } override fun onBalancesAndLimitsClick() { + stateController.showBottomSheet(getBalancesAndLimitsConfig()) + } + + // TODO: Implement + private fun getBalancesAndLimitsConfig() = BalancesAndLimitsBottomSheetConfig( + currency = "USDT", + balance = BalancesAndLimitsBottomSheetConfig.Balance( + totalBalance = "492.45", + availableBalance = "392.45", + blockedBalance = "36.00", + debit = "00.00", + pending = "20.99", + amlVerified = "356.45", + ), + limit = BalancesAndLimitsBottomSheetConfig.Limit( + availableBy = "Nov, 11", + inStore = "563.00", + other = "100.00", + singleTransaction = "100.00", + ), + onBalanceInfoClick = this::showBalanceInfo, + onLimitInfoClick = this::showLimitInfo, + ) + + private fun showBalanceInfo() { + eventSender.send(WalletEvent.ShowToast(stringReference(value = "Not implemented yet"))) + } + + private fun showLimitInfo() { eventSender.send(WalletEvent.ShowToast(stringReference(value = "Not implemented yet"))) } } \ No newline at end of file