Updated on 2026-08-14

This commit is contained in:
Tangem 2025-11-10 19:24:43 +05:00
parent 939dcf8405
commit 7c9e533757
10 changed files with 242 additions and 228 deletions

View file

@ -258,7 +258,7 @@
<string name="common_enable">Enable</string>
<string name="common_enabled">Enabled</string>
<string name="common_error">Error</string>
<string name="common_estimated_fee">Network service fee</string>
<string name="common_estimated_fee">Top-up network fee</string>
<string name="common_exchange">Swap</string>
<string name="common_explore">Explore</string>
<string name="common_explore_transaction_history">Explore transaction history</string>
@ -274,7 +274,7 @@
<string name="common_free">Free</string>
<string name="common_from">From</string>
<string name="common_generate_addresses">Synchronize addresses</string>
<string name="common_get_started">Get started</string>
<string name="common_get_started">Learn more</string>
<string name="common_get_token">Get token</string>
<string name="common_go_to_provider">Go to provider</string>
<string name="common_go_to_token">Go to token</string>
@ -573,8 +573,8 @@
<string name="hw_backup_hardware_upgrade_title">Upgrade current wallet</string>
<string name="hw_backup_need_action">Go to backup</string>
<string name="hw_backup_need_description">Please back up your wallet before creating an access code.</string>
<string name="hw_backup_need_finish_first">Finish Backup First</string>
<string name="hw_backup_need_title">Finalize backup first</string>
<string name="hw_backup_need_finish_first">Finish backup first</string>
<string name="hw_backup_no_backup">Incomplete</string>
<string name="hw_backup_section_other_title">Other methods</string>
<string name="hw_backup_seed_description">Physical devices that securely store your private key offline.</string>
@ -1374,6 +1374,7 @@
<string name="tangem_pay_status_completed">Completed</string>
<string name="tangem_pay_status_declined">Declined</string>
<string name="tangem_pay_status_pending">Pending</string>
<string name="tangem_pay_terms_fees_limits">Terms, Fees &amp; Limits</string>
<string name="tangem_pay_transaction_declined_notification_text">The bank rejected this transaction request.</string>
<string name="tangem_pay_transaction_fee_notification_text">This fee goes to cover the cost of handling your transfer.</string>
<string name="tangem_pay_unfreeze_card_alert_body">Keep using your money. You can freeze anytime.</string>
@ -1410,12 +1411,12 @@
<string name="tangempay_kyc_in_progress_notification_button">View Status</string>
<string name="tangempay_kyc_in_progress_notification_title">KYC in progress for Tangem Pay</string>
<string name="tangempay_onboarding_get_card_button_text">Get card</string>
<string name="tangempay_onboarding_pay_description">Add to your wallet and pay with your phone anywhere.</string>
<string name="tangempay_onboarding_pay_title">Apple Pay &amp; Google Pay</string>
<string name="tangempay_onboarding_purchases_description">Use your USDC balance to pay for everyday purchases seamlessly.</string>
<string name="tangempay_onboarding_purchases_title">Everyday purchases</string>
<string name="tangempay_onboarding_security_description">Your card details are protected — full control in the app.</string>
<string name="tangempay_onboarding_security_title">Built-in security</string>
<string name="tangempay_onboarding_pay_description">Spend your crypto anywhere</string>
<string name="tangempay_onboarding_pay_title">With digital card that works with Apple Pay and Google Pay</string>
<string name="tangempay_onboarding_purchases_description">There are no additional fees for purchases</string>
<string name="tangempay_onboarding_purchases_title">Pay exactly what you see</string>
<string name="tangempay_onboarding_security_description">A separate payment account will be created without disclosing your addresses and assets</string>
<string name="tangempay_onboarding_security_title">Unrivaled privacy</string>
<string name="tangempay_onboarding_title">Get your free Crypto Card\nin minutes</string>
<string name="tangempay_title">Tangem Pay</string>
<string name="this_is_my_wallet_title">This is my wallet</string>
@ -1880,7 +1881,7 @@
<string name="yield_module_alert_description">With Yield mode active, all future deposits to this address will go to Aave. You can still manage your funds freely.</string>
<string name="yield_module_alert_title">Your %s is supplied to Aave</string>
<string name="yield_module_amount_not_transfered_to_aave_title">Supplying %1$s %2$s to Aave is pending</string>
<string name="yield_module_approve_needed_notification_cta">Give Approve</string>
<string name="yield_module_approve_needed_notification_cta">Approve</string>
<string name="yield_module_approve_needed_notification_description">Your tokens approval has been revoked. Grant it again to resume service functionality.</string>
<string name="yield_module_approve_needed_notification_title">Approve needed</string>
<string name="yield_module_approve_sheet_fee_note">The fee will be taken out, and your assets will be lent again.</string>
@ -1909,7 +1910,7 @@
<string name="yield_module_fee_policy_sheet_max_fee_title">Maximum fee</string>
<string name="yield_module_fee_policy_sheet_min_amount_note">The minimum amount is calculated based on the current network fee so that it does not exceed 4%% of the top-up amount, which makes the minimum %1$s (%2$s).</string>
<string name="yield_module_fee_policy_sheet_min_amount_title">Minimum top-up</string>
<string name="yield_module_fee_policy_sheet_title">Fee policy</string>
<string name="yield_module_fee_policy_sheet_title">Top-up fee policy</string>
<string name="yield_module_fee_policy_tangem_service_fee_title">Tangem also takes a 15% service fee on yield earned.</string>
<string name="yield_module_high_fee_error">Your funds will be automatically supplied to Aave once network fees are lower or your balance meets the minimum required amount.</string>
<string name="yield_module_historical_returns">Historical returns</string>
@ -1936,7 +1937,7 @@
<string name="yield_module_receive_sheet_description">When you top up, your funds will be automatically sent to Aave to start earning interest. %s will be deducted to cover the transaction fee.</string>
<string name="yield_module_start_earning">Supply assets</string>
<string name="yield_module_start_earning_sheet_description">Your %s will be supplied to Aave, but will remain manageable.</string>
<string name="yield_module_start_earning_sheet_fee_policy">See fee policy</string>
<string name="yield_module_start_earning_sheet_fee_policy">See top-up fee policy</string>
<string name="yield_module_start_earning_sheet_next_deposits">Your next top-ups will be automatically supplied to Aave.</string>
<string name="yield_module_status_active">Active</string>
<string name="yield_module_status_paused">Paused</string>
@ -1950,7 +1951,7 @@
<string name="yield_module_token_details_earn_notification_description">Interest accrues automatically.</string>
<string name="yield_module_token_details_earn_notification_earning_on_your_balance_subtitle">Interest accrues automatically</string>
<string name="yield_module_token_details_earn_notification_earning_on_your_balance_title">Yield mode</string>
<string name="yield_module_token_details_earn_notification_processing">Processing your deposit</string>
<string name="yield_module_token_details_earn_notification_processing">Processing your top-up</string>
<string name="yield_module_token_details_earn_notification_title">Yield Mode</string>
<string name="yield_module_transfer_mode_automatic">Automatic</string>
<string name="yield_module_unable_to_cover_fee_description">Deposit some %1$s %2$s to cover the network fee for transactions</string>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View file

@ -16,6 +16,8 @@ dependencies {
implementation(projects.core.decompose)
implementation(projects.core.ui)
implementation(projects.core.error)
implementation(projects.core.navigation)
implementation(deps.arrow.core)
implementation(deps.arrow.core)
/** Common */

View file

@ -6,14 +6,17 @@ import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.decompose.navigation.Router
import com.tangem.core.navigation.url.UrlOpener
import com.tangem.domain.pay.repository.OnboardingRepository
import com.tangem.domain.pay.usecase.ProduceTangemPayInitialDataUseCase
import com.tangem.features.tangempay.components.TangemPayOnboardingComponent
import com.tangem.features.tangempay.model.transformers.TangemPayOnboardingButtonLoadingTransformer
import com.tangem.features.tangempay.ui.TangemPayOnboardingScreenState
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.update
import com.tangem.utils.transformer.update as transformerUpdate
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
@ -26,6 +29,7 @@ internal class TangemPayOnboardingModel @Inject constructor(
override val dispatchers: CoroutineDispatcherProvider,
private val repository: OnboardingRepository,
private val produceInitialDataUseCase: ProduceTangemPayInitialDataUseCase,
private val urlOpener: UrlOpener,
) : Model() {
private val params = paramsContainer.require<TangemPayOnboardingComponent.Params>()
@ -48,7 +52,16 @@ internal class TangemPayOnboardingModel @Inject constructor(
}
private fun showOnboarding() {
uiState.update { it.copy(fullScreenLoading = false) }
uiState.update {
TangemPayOnboardingScreenState.Content(
onBack = it.onBack,
onTermsClick = ::onTermsClick,
buttonConfig = TangemPayOnboardingScreenState.Content.ButtonConfig(
isLoading = false,
onClick = ::onGetCardClick,
),
)
}
}
private suspend fun checkCustomerInfo() {
@ -57,8 +70,7 @@ internal class TangemPayOnboardingModel @Inject constructor(
when {
!customerInfo.isKycApproved -> {
when (params) {
is TangemPayOnboardingComponent.Params.Deeplink ->
uiState.value = uiState.value.copy(fullScreenLoading = false)
is TangemPayOnboardingComponent.Params.Deeplink -> showOnboarding()
else -> openKyc()
}
}
@ -68,13 +80,17 @@ internal class TangemPayOnboardingModel @Inject constructor(
.onLeft { back() }
}
private fun onTermsClick() {
urlOpener.openUrl("https://tangem.com/docs/en/tangem-visa-tariffs.pdf")
}
private fun onGetCardClick() {
uiState.update { it.copy(buttonLoading = true) }
uiState.transformerUpdate(TangemPayOnboardingButtonLoadingTransformer(isLoading = true))
modelScope.launch {
val result = produceInitialDataUseCase()
if (result.isLeft()) {
Timber.e("Error producing initial data: ${result.leftOrNull()?.message}")
uiState.update { it.copy(buttonLoading = false) }
uiState.transformerUpdate(TangemPayOnboardingButtonLoadingTransformer(isLoading = false))
return@launch
}
@ -82,7 +98,7 @@ internal class TangemPayOnboardingModel @Inject constructor(
.fold(
ifLeft = {
Timber.e("Error getCustomerInfo: ${it.errorCode}")
uiState.update { it.copy(buttonLoading = false) }
uiState.transformerUpdate(TangemPayOnboardingButtonLoadingTransformer(isLoading = false))
},
ifRight = { customerInfo ->
if (customerInfo.isKycApproved) {
@ -104,11 +120,6 @@ internal class TangemPayOnboardingModel @Inject constructor(
}
private fun getInitialState(): TangemPayOnboardingScreenState {
return TangemPayOnboardingScreenState(
fullScreenLoading = true,
buttonLoading = false,
onGetCardClick = ::onGetCardClick,
onBackClick = ::back,
)
return TangemPayOnboardingScreenState.Loading(onBack = ::back)
}
}

View file

@ -0,0 +1,14 @@
package com.tangem.features.tangempay.model.transformers
import com.tangem.features.tangempay.ui.TangemPayOnboardingScreenState
import com.tangem.utils.transformer.Transformer
internal class TangemPayOnboardingButtonLoadingTransformer(
private val isLoading: Boolean,
) : Transformer<TangemPayOnboardingScreenState> {
override fun transform(prevState: TangemPayOnboardingScreenState): TangemPayOnboardingScreenState {
val contentState = prevState as? TangemPayOnboardingScreenState.Content ?: return prevState
val updatedButtonConfig = contentState.buttonConfig.copy(isLoading = isLoading)
return contentState.copy(buttonConfig = updatedButtonConfig)
}
}

View file

@ -1,18 +1,34 @@
package com.tangem.features.tangempay.ui
import android.content.res.Configuration
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.layout.systemBarsPadding
import androidx.annotation.DrawableRes
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Icon
import androidx.compose.material3.Scaffold
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.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
import androidx.compose.ui.unit.dp
import com.tangem.common.ui.navigationButtons.NavigationButton
import com.tangem.common.ui.navigationButtons.NavigationPrimaryButton
import com.tangem.core.ui.R
import com.tangem.core.ui.components.SecondaryButton
import com.tangem.core.ui.components.appbar.AppBarWithBackButton
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.core.ui.utils.WindowInsetsZero
@ -23,27 +39,166 @@ internal fun TandemPayOnboardingScreen(state: TangemPayOnboardingScreenState, mo
topBar = {
AppBarWithBackButton(
modifier = Modifier.statusBarsPadding(),
onBackClick = state.onBackClick,
onBackClick = state.onBack,
iconRes = R.drawable.ic_back_24,
)
},
contentWindowInsets = WindowInsetsZero,
content = { paddingValues ->
TangemPayOnboardingContent(
modifier = Modifier
.padding(paddingValues)
.fillMaxSize(),
state = state,
onButtonClick = state.onGetCardClick,
)
val contentModifier = Modifier
.systemBarsPadding()
.padding(paddingValues)
.fillMaxSize()
when (state) {
is TangemPayOnboardingScreenState.Loading -> TangemPayOnboardingLoading(modifier = contentModifier)
is TangemPayOnboardingScreenState.Content -> TangemPayOnboardingContent(
state = state,
modifier = contentModifier,
)
}
},
)
}
@Composable
private fun TangemPayOnboardingLoading(modifier: Modifier = Modifier) {
Box(modifier = modifier, contentAlignment = Alignment.Center) {
CircularProgressIndicator(
modifier = Modifier,
color = TangemTheme.colors.icon.primary1,
)
}
}
@Composable
private fun TangemPayOnboardingContent(state: TangemPayOnboardingScreenState.Content, modifier: Modifier = Modifier) {
Column(modifier = modifier.padding(horizontal = 16.dp)) {
Column(
modifier = Modifier
.padding(bottom = 16.dp)
.weight(1f)
.verticalScroll(rememberScrollState()),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
) {
Image(
painter = painterResource(id = R.drawable.img_tangem_pay_visa),
contentDescription = null,
modifier = Modifier.size(width = 200.dp, height = 130.dp),
)
Text(
text = stringResourceSafe(R.string.tangempay_onboarding_title),
style = TangemTheme.typography.h2,
color = TangemTheme.colors.text.primary1,
textAlign = TextAlign.Center,
modifier = Modifier
.padding(top = 24.dp)
.padding(horizontal = 12.dp)
.fillMaxWidth(),
)
TangemPayOnboardingBlocks(
modifier = Modifier
.padding(top = 24.dp)
.padding(horizontal = 12.dp),
)
}
FooterButtons(
modifier = Modifier.padding(bottom = 16.dp),
primaryButtonConfig = state.buttonConfig,
onTermsClick = state.onTermsClick,
)
}
}
@Composable
internal fun TangemPayOnboardingBlocks(modifier: Modifier = Modifier) {
Column(
modifier = modifier,
verticalArrangement = Arrangement.spacedBy(20.dp),
) {
TangemPayOnboardingBlock(
painterRes = R.drawable.ic_security_check_22,
titleRef = TextReference.Res(R.string.tangempay_onboarding_security_title),
descriptionRef = TextReference.Res(R.string.tangempay_onboarding_security_description),
)
TangemPayOnboardingBlock(
painterRes = R.drawable.ic_shopping_basket_22,
titleRef = TextReference.Res(R.string.tangempay_onboarding_purchases_title),
descriptionRef = TextReference.Res(R.string.tangempay_onboarding_purchases_description),
)
TangemPayOnboardingBlock(
painterRes = R.drawable.ic_credit_card_add_22,
titleRef = TextReference.Res(R.string.tangempay_onboarding_pay_title),
descriptionRef = TextReference.Res(R.string.tangempay_onboarding_pay_description),
)
}
}
@Composable
private fun TangemPayOnboardingBlock(
@DrawableRes painterRes: Int,
titleRef: TextReference,
descriptionRef: TextReference,
modifier: Modifier = Modifier,
) {
Row(modifier = modifier) {
Icon(
painter = painterResource(id = painterRes),
contentDescription = null,
modifier = Modifier.size(width = 24.dp, height = 24.dp),
tint = TangemTheme.colors.icon.accent,
)
Column(
modifier = Modifier
.padding(start = 12.dp)
.fillMaxWidth(),
) {
Text(
text = titleRef.resolveReference(),
style = TangemTheme.typography.subtitle1,
color = TangemTheme.colors.text.primary1,
)
Text(
text = descriptionRef.resolveReference(),
style = TangemTheme.typography.body2,
color = TangemTheme.colors.text.secondary,
)
}
}
}
@Composable
private fun FooterButtons(
primaryButtonConfig: TangemPayOnboardingScreenState.Content.ButtonConfig,
onTermsClick: () -> Unit,
modifier: Modifier = Modifier,
) {
Column(modifier = modifier, verticalArrangement = Arrangement.spacedBy(8.dp)) {
SecondaryButton(
modifier = Modifier.fillMaxWidth(),
text = stringResourceSafe(R.string.tangem_pay_terms_fees_limits),
onClick = onTermsClick,
)
NavigationPrimaryButton(
primaryButton = NavigationButton(
textReference = resourceReference(R.string.tangempay_onboarding_get_card_button_text),
iconRes = R.drawable.ic_tangem_24,
isIconVisible = true,
shouldShowProgress = primaryButtonConfig.isLoading,
onClick = primaryButtonConfig.onClick,
),
)
}
}
@Preview(showBackground = true)
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun PreviewDarkTheme(
private fun TandemPayOnboardingScreenPreview(
@PreviewParameter(TangemPayOnboardingScreenStateProvider::class)
state: TangemPayOnboardingScreenState,
) {
@ -55,23 +210,16 @@ private fun PreviewDarkTheme(
private class TangemPayOnboardingScreenStateProvider :
CollectionPreviewParameterProvider<TangemPayOnboardingScreenState>(
listOf(
TangemPayOnboardingScreenState(
fullScreenLoading = true,
buttonLoading = false,
onGetCardClick = {},
onBackClick = {},
TangemPayOnboardingScreenState.Loading(onBack = {}),
TangemPayOnboardingScreenState.Content(
onBack = {},
onTermsClick = {},
buttonConfig = TangemPayOnboardingScreenState.Content.ButtonConfig(isLoading = false, onClick = {}),
),
TangemPayOnboardingScreenState(
fullScreenLoading = false,
buttonLoading = false,
onGetCardClick = {},
onBackClick = {},
),
TangemPayOnboardingScreenState(
fullScreenLoading = false,
buttonLoading = true,
onGetCardClick = {},
onBackClick = {},
TangemPayOnboardingScreenState.Content(
onBack = {},
onTermsClick = {},
buttonConfig = TangemPayOnboardingScreenState.Content.ButtonConfig(isLoading = true, onClick = {}),
),
),
)

View file

@ -1,48 +0,0 @@
package com.tangem.features.tangempay.ui
import androidx.annotation.DrawableRes
import androidx.compose.foundation.layout.*
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.res.TangemTheme
@Composable
internal fun TangemPayOnboardingBlock(
@DrawableRes painterRes: Int,
titleRef: TextReference,
descriptionRef: TextReference,
modifier: Modifier = Modifier,
) {
Row(
modifier = modifier
.padding(start = 32.dp, end = 32.dp),
) {
Icon(
painter = painterResource(id = painterRes),
contentDescription = null,
modifier = Modifier
.width(24.dp)
.height(24.dp),
)
Column(
modifier = Modifier.padding(start = 12.dp),
) {
Text(
text = titleRef.resolveReference(),
style = TangemTheme.typography.subtitle1,
color = TangemTheme.colors.text.primary1,
)
Text(
text = descriptionRef.resolveReference(),
style = TangemTheme.typography.body2,
color = TangemTheme.colors.text.secondary,
)
}
}
}

View file

@ -1,36 +0,0 @@
package com.tangem.features.tangempay.ui
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.R
import com.tangem.core.ui.components.SpacerH
import com.tangem.core.ui.extensions.TextReference
@Composable
internal fun TangemPayOnboardingBLocks(modifier: Modifier = Modifier) {
TangemPayOnboardingBlock(
modifier = modifier,
painterRes = R.drawable.ic_security_check_22,
titleRef = TextReference.Res(R.string.tangempay_onboarding_security_title),
descriptionRef = TextReference.Res(R.string.tangempay_onboarding_security_description),
)
SpacerH(18.dp)
TangemPayOnboardingBlock(
modifier = modifier,
painterRes = R.drawable.ic_shopping_basket_22,
titleRef = TextReference.Res(R.string.tangempay_onboarding_purchases_title),
descriptionRef = TextReference.Res(R.string.tangempay_onboarding_purchases_description),
)
SpacerH(18.dp)
TangemPayOnboardingBlock(
modifier = modifier,
painterRes = R.drawable.ic_credit_card_add_22,
titleRef = TextReference.Res(R.string.tangempay_onboarding_pay_title),
descriptionRef = TextReference.Res(R.string.tangempay_onboarding_pay_description),
)
}

View file

@ -1,84 +0,0 @@
package com.tangem.features.tangempay.ui
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.*
import androidx.compose.material3.CircularProgressIndicator
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.text.style.TextAlign
import androidx.compose.ui.unit.dp
import com.tangem.common.ui.navigationButtons.NavigationButton
import com.tangem.common.ui.navigationButtons.NavigationPrimaryButton
import com.tangem.core.ui.components.SpacerH
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.TangemTheme
import com.tangem.features.tangempay.onboarding.impl.R
@Composable
internal fun TangemPayOnboardingContent(
state: TangemPayOnboardingScreenState,
onButtonClick: () -> Unit,
modifier: Modifier = Modifier,
) {
if (state.fullScreenLoading) {
Box(
modifier = modifier.fillMaxSize(),
contentAlignment = Alignment.Center,
) {
CircularProgressIndicator(
modifier = Modifier,
color = TangemTheme.colors.icon.primary1,
)
}
} else {
Column(
modifier
.fillMaxSize()
.navigationBarsPadding(),
) {
Column(
modifier = Modifier
.weight(1f)
.padding(top = 24.dp, bottom = 32.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Image(
painter = painterResource(id = R.drawable.img_tangem_pay_onboarding),
contentDescription = null,
modifier = Modifier
.height(250.dp)
.fillMaxWidth(),
)
Text(
text = stringResourceSafe(R.string.tangempay_onboarding_title),
style = TangemTheme.typography.h2,
color = TangemTheme.colors.text.primary1,
textAlign = TextAlign.Center,
)
SpacerH(32.dp)
TangemPayOnboardingBLocks()
}
NavigationPrimaryButton(
modifier = Modifier
.imePadding()
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)
.fillMaxWidth(),
primaryButton = NavigationButton(
textReference = resourceReference(R.string.tangempay_onboarding_get_card_button_text),
iconRes = R.drawable.ic_tangem_24,
isIconVisible = true,
shouldShowProgress = state.buttonLoading,
onClick = onButtonClick,
),
)
}
}
}

View file

@ -3,9 +3,15 @@ package com.tangem.features.tangempay.ui
import javax.annotation.concurrent.Immutable
@Immutable
internal data class TangemPayOnboardingScreenState(
val fullScreenLoading: Boolean,
val buttonLoading: Boolean,
val onGetCardClick: () -> Unit,
val onBackClick: () -> Unit,
)
internal sealed class TangemPayOnboardingScreenState {
abstract val onBack: () -> Unit
data class Loading(override val onBack: () -> Unit) : TangemPayOnboardingScreenState()
data class Content(
override val onBack: () -> Unit,
val onTermsClick: () -> Unit,
val buttonConfig: ButtonConfig,
) : TangemPayOnboardingScreenState() {
data class ButtonConfig(val isLoading: Boolean, val onClick: () -> Unit)
}
}