Updated on 2026-08-14
This commit is contained in:
parent
56b064b1a0
commit
b47cc52e70
14 changed files with 546 additions and 9 deletions
|
|
@ -0,0 +1,37 @@
|
|||
package com.tangem.feature.referral.models
|
||||
|
||||
data class ReferralStateHolder(
|
||||
val headerState: HeaderState,
|
||||
val referralInfoState: ReferralInfoState,
|
||||
val effects: Effects,
|
||||
) {
|
||||
|
||||
data class HeaderState(val onBackClicked: () -> Unit)
|
||||
|
||||
sealed interface ReferralInfoContentState
|
||||
|
||||
sealed interface ReferralInfoState {
|
||||
|
||||
data class ParticipantContent(
|
||||
val award: String,
|
||||
val address: String,
|
||||
val discount: String,
|
||||
val onAgreementClicked: () -> Unit,
|
||||
val onParticipateClicked: () -> Unit,
|
||||
) : ReferralInfoState, ReferralInfoContentState
|
||||
|
||||
data class NonParticipantContent(
|
||||
val award: String,
|
||||
val discount: String,
|
||||
val purchasedWalletCount: Int,
|
||||
val code: String,
|
||||
val onCopyClicked: () -> Unit,
|
||||
val onShareClicked: () -> Unit,
|
||||
val onAgreementClicked: () -> Unit,
|
||||
) : ReferralInfoState, ReferralInfoContentState
|
||||
|
||||
object Loading : ReferralInfoState
|
||||
}
|
||||
|
||||
data class Effects(val showErrorToast: Boolean)
|
||||
}
|
||||
|
|
@ -0,0 +1,362 @@
|
|||
package com.tangem.feature.referral.ui
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.ColumnScope
|
||||
import androidx.compose.foundation.layout.Row
|
||||
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.shape.RoundedCornerShape
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.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.dimensionResource
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.SpanStyle
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.withStyle
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.tangem.core.ui.components.AppBarWithBackButton
|
||||
import com.tangem.core.ui.components.VerticalSpacer
|
||||
import com.tangem.core.ui.res.ButtonColorType
|
||||
import com.tangem.core.ui.res.IconColorType
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TextColorType
|
||||
import com.tangem.core.ui.res.White
|
||||
import com.tangem.core.ui.res.buttonColor
|
||||
import com.tangem.core.ui.res.iconColor
|
||||
import com.tangem.core.ui.res.textColor
|
||||
import com.tangem.feature.referral.models.ReferralStateHolder
|
||||
import com.tangem.feature.referral.models.ReferralStateHolder.ReferralInfoState
|
||||
import com.tangem.feature.referral.presentation.R
|
||||
import com.valentinilk.shimmer.shimmer
|
||||
|
||||
@Preview(widthDp = 360, showBackground = true)
|
||||
@Composable
|
||||
fun Preview_ReferralScreen_Participant_InLightTheme() {
|
||||
TangemTheme(isDarkTheme = false) {
|
||||
ReferralScreen(
|
||||
stateHolder = ReferralStateHolder(
|
||||
headerState = ReferralStateHolder.HeaderState(onBackClicked = {}),
|
||||
referralInfoState = ReferralInfoState.ParticipantContent(
|
||||
award = "10 USDT",
|
||||
address = "ma80...zk8q2",
|
||||
discount = "10%",
|
||||
onAgreementClicked = {},
|
||||
onParticipateClicked = {},
|
||||
),
|
||||
effects = ReferralStateHolder.Effects(showErrorToast = false),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(widthDp = 360, showBackground = true)
|
||||
@Composable
|
||||
fun Preview_ReferralScreen_Participant_InDarkTheme() {
|
||||
TangemTheme(isDarkTheme = true) {
|
||||
ReferralScreen(
|
||||
stateHolder = ReferralStateHolder(
|
||||
headerState = ReferralStateHolder.HeaderState(onBackClicked = {}),
|
||||
referralInfoState = ReferralInfoState.ParticipantContent(
|
||||
award = "10 USDT",
|
||||
address = "ma80...zk8q2",
|
||||
discount = "10%",
|
||||
onAgreementClicked = {},
|
||||
onParticipateClicked = {},
|
||||
),
|
||||
effects = ReferralStateHolder.Effects(showErrorToast = false),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(widthDp = 360, showBackground = true)
|
||||
@Composable
|
||||
fun Preview_ReferralScreen_NonParticipant_InLightTheme() {
|
||||
TangemTheme(isDarkTheme = false) {
|
||||
ReferralScreen(
|
||||
stateHolder = ReferralStateHolder(
|
||||
headerState = ReferralStateHolder.HeaderState(onBackClicked = {}),
|
||||
referralInfoState = ReferralInfoState.NonParticipantContent(
|
||||
award = "10 USDT",
|
||||
discount = "10%",
|
||||
purchasedWalletCount = 3,
|
||||
code = "x4JdK",
|
||||
onCopyClicked = {},
|
||||
onShareClicked = {},
|
||||
onAgreementClicked = {},
|
||||
),
|
||||
effects = ReferralStateHolder.Effects(showErrorToast = false),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(widthDp = 360, showBackground = true)
|
||||
@Composable
|
||||
fun Preview_ReferralScreen_NonParticipant_InDarkTheme() {
|
||||
TangemTheme(isDarkTheme = true) {
|
||||
ReferralScreen(
|
||||
stateHolder = ReferralStateHolder(
|
||||
headerState = ReferralStateHolder.HeaderState(onBackClicked = {}),
|
||||
referralInfoState = ReferralInfoState.NonParticipantContent(
|
||||
award = "10 USDT",
|
||||
discount = "10%",
|
||||
purchasedWalletCount = 3,
|
||||
code = "x4JdK",
|
||||
onCopyClicked = {},
|
||||
onShareClicked = {},
|
||||
onAgreementClicked = {},
|
||||
),
|
||||
effects = ReferralStateHolder.Effects(showErrorToast = false),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(widthDp = 360, showBackground = true)
|
||||
@Composable
|
||||
fun Preview_ReferralScreen_Loading_InLightTheme() {
|
||||
TangemTheme(isDarkTheme = false) {
|
||||
ReferralScreen(
|
||||
stateHolder = ReferralStateHolder(
|
||||
headerState = ReferralStateHolder.HeaderState(onBackClicked = {}),
|
||||
referralInfoState = ReferralInfoState.Loading,
|
||||
effects = ReferralStateHolder.Effects(showErrorToast = false),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(widthDp = 360, showBackground = true)
|
||||
@Composable
|
||||
fun Preview_ReferralScreen_Loading_InDarkTheme() {
|
||||
TangemTheme(isDarkTheme = true) {
|
||||
ReferralScreen(
|
||||
stateHolder = ReferralStateHolder(
|
||||
headerState = ReferralStateHolder.HeaderState(onBackClicked = {}),
|
||||
referralInfoState = ReferralInfoState.Loading,
|
||||
effects = ReferralStateHolder.Effects(showErrorToast = false),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Referral program screen for participant and non-participant
|
||||
*
|
||||
* @param stateHolder state holder
|
||||
*/
|
||||
@Composable
|
||||
fun ReferralScreen(stateHolder: ReferralStateHolder) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.background(color = MaterialTheme.colors.primary)
|
||||
.fillMaxSize(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Header(stateHolder = stateHolder)
|
||||
VerticalSpacer(spaceResId = R.dimen.spacing16)
|
||||
ReferralInfo(stateHolder = stateHolder)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ColumnScope.Header(stateHolder: ReferralStateHolder) {
|
||||
AppBar(stateHolder = stateHolder)
|
||||
Image(
|
||||
painter = painterResource(R.drawable.ill_businessman_3d),
|
||||
contentDescription = null,
|
||||
modifier = Modifier
|
||||
.padding(horizontal = dimensionResource(id = R.dimen.spacing32))
|
||||
.fillMaxWidth()
|
||||
.height(dimensionResource(R.dimen.size200)),
|
||||
)
|
||||
VerticalSpacer(spaceResId = R.dimen.spacing24)
|
||||
Text(
|
||||
text = stringResource(id = R.string.referral_title),
|
||||
modifier = Modifier.padding(horizontal = dimensionResource(R.dimen.spacing50)),
|
||||
color = MaterialTheme.colors.textColor(type = TextColorType.PRIMARY1),
|
||||
textAlign = TextAlign.Center,
|
||||
maxLines = 2,
|
||||
style = MaterialTheme.typography.h2,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ReferralInfo(stateHolder: ReferralStateHolder) {
|
||||
when (val state = stateHolder.referralInfoState) {
|
||||
is ReferralInfoState.ParticipantContent,
|
||||
is ReferralInfoState.NonParticipantContent -> {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(dimensionResource(id = R.dimen.spacing32))) {
|
||||
ConditionForYou(state = state as ReferralStateHolder.ReferralInfoContentState)
|
||||
ConditionForYourFriend(state = state)
|
||||
}
|
||||
}
|
||||
is ReferralInfoState.Loading -> {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(dimensionResource(id = R.dimen.spacing32))) {
|
||||
LoadingCondition(iconResId = R.drawable.ic_tether)
|
||||
LoadingCondition(iconResId = R.drawable.ic_discount)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun AppBar(stateHolder: ReferralStateHolder) {
|
||||
AppBarWithBackButton(
|
||||
text = stringResource(R.string.details_referral_title),
|
||||
onBackClick = stateHolder.headerState.onBackClicked,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ConditionForYou(state: ReferralStateHolder.ReferralInfoContentState) {
|
||||
Condition(iconResId = R.drawable.ic_tether) {
|
||||
when (state) {
|
||||
is ReferralInfoState.ParticipantContent -> InfoForYou(award = state.award, address = state.address)
|
||||
is ReferralInfoState.NonParticipantContent -> InfoForYou(award = state.award)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ConditionForYourFriend(state: ReferralStateHolder.ReferralInfoContentState) {
|
||||
Condition(iconResId = R.drawable.ic_discount) {
|
||||
when (state) {
|
||||
is ReferralInfoState.ParticipantContent -> InfoForYourFriend(discount = state.discount)
|
||||
is ReferralInfoState.NonParticipantContent -> InfoForYourFriend(discount = state.discount)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun LoadingCondition(@DrawableRes iconResId: Int) {
|
||||
Condition(iconResId = iconResId) {
|
||||
ShimmerCondition()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Condition(@DrawableRes iconResId: Int, infoBlock: @Composable () -> Unit) {
|
||||
Row(
|
||||
modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.spacing16)),
|
||||
horizontalArrangement = Arrangement.spacedBy(dimensionResource(id = R.dimen.spacing12)),
|
||||
verticalAlignment = Alignment.Top,
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.background(
|
||||
color = MaterialTheme.colors.buttonColor(type = ButtonColorType.SECONDARY),
|
||||
shape = RoundedCornerShape(dimensionResource(id = R.dimen.radius16)),
|
||||
)
|
||||
.size(dimensionResource(id = R.dimen.size56)),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(id = iconResId),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(dimensionResource(id = R.dimen.size28)),
|
||||
tint = MaterialTheme.colors.iconColor(type = IconColorType.PRIMARY1),
|
||||
)
|
||||
}
|
||||
infoBlock()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun InfoForYou(award: String, address: String? = null) {
|
||||
ConditionInfo(title = stringResource(id = R.string.referral_point_currencies_title)) {
|
||||
Text(
|
||||
text = buildAnnotatedString {
|
||||
append(stringResource(id = R.string.referral_point_currencies_description_prefix))
|
||||
withStyle(SpanStyle(color = MaterialTheme.colors.textColor(type = TextColorType.PRIMARY1))) {
|
||||
append(" $award ")
|
||||
}
|
||||
append(
|
||||
String.format(
|
||||
stringResource(id = R.string.referral_point_currencies_description_suffix),
|
||||
if (!address.isNullOrBlank()) address else "",
|
||||
),
|
||||
)
|
||||
},
|
||||
color = MaterialTheme.colors.textColor(type = TextColorType.TERTIARY),
|
||||
style = MaterialTheme.typography.body2,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun InfoForYourFriend(discount: String) {
|
||||
ConditionInfo(title = stringResource(id = R.string.referral_point_discount_title)) {
|
||||
Text(
|
||||
text = buildString {
|
||||
append(stringResource(id = R.string.referral_point_discount_description_prefix))
|
||||
append(
|
||||
String.format(
|
||||
stringResource(id = R.string.referral_point_discount_description_value),
|
||||
" $discount",
|
||||
),
|
||||
)
|
||||
append(" ")
|
||||
append(stringResource(id = R.string.referral_point_discount_description_suffix))
|
||||
},
|
||||
color = MaterialTheme.colors.textColor(type = TextColorType.TERTIARY),
|
||||
style = MaterialTheme.typography.body2,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ConditionInfo(title: String, subtitleContent: @Composable () -> Unit) {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(dimensionResource(id = R.dimen.spacing2))) {
|
||||
Text(
|
||||
text = title,
|
||||
color = MaterialTheme.colors.textColor(type = TextColorType.PRIMARY1),
|
||||
style = MaterialTheme.typography.subtitle1,
|
||||
)
|
||||
subtitleContent()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ShimmerCondition() {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = dimensionResource(id = R.dimen.spacing4))
|
||||
.shimmer(),
|
||||
verticalArrangement = Arrangement.spacedBy(dimensionResource(id = R.dimen.spacing10)),
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.clip(RoundedCornerShape(dimensionResource(id = R.dimen.radius6)))
|
||||
.width(dimensionResource(id = R.dimen.size102))
|
||||
.height(dimensionResource(id = R.dimen.size16))
|
||||
.background(White),
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.clip(RoundedCornerShape(dimensionResource(id = R.dimen.radius6)))
|
||||
.width(dimensionResource(id = R.dimen.size40))
|
||||
.height(dimensionResource(id = R.dimen.size11))
|
||||
.background(White),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="details_referral_title">Реферальная программа</string>
|
||||
<string name="referral_title">Приведи друга в Tangem</string>
|
||||
<string name="referral_point_currencies_title">Вы</string>
|
||||
<string name="referral_point_currencies_description_prefix">Получите</string>
|
||||
<string name="referral_point_currencies_description_suffix">за каждый кошелек, который купит ваш друг на ваш адрес в сети Tron %@</string>
|
||||
<string name="referral_point_discount_title">Ваш друг</string>
|
||||
<string name="referral_point_discount_description_prefix">Получит</string>
|
||||
<string name="referral_point_discount_description_value">%@ скидку</string>
|
||||
<string name="referral_point_discount_description_suffix">при покупке карточки на сайте tangem.com</string>
|
||||
<string name="referral_tou_not_enroled_prefix">Нажимая на эту кнопку вы принимаете</string>
|
||||
<string name="common_terms_and_conditions">условия участия</string>
|
||||
<string name="referral_tou_suffix">в реферальной программе</string>
|
||||
<string name="referral_button_participate">Участвовать</string>
|
||||
<string name="referral_tou_enroled_prefix">Вы приняли</string>
|
||||
<string name="referral_promo_code_title">Ваш персональный код</string>
|
||||
<string name="referral_wallets_purchased_count">%d кошельков</string>
|
||||
<string name="referral_friends_bought_title">Ваши друзья купили</string>
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="details_referral_title">Referral program</string>
|
||||
<string name="referral_title">Refer your friends to Tangem</string>
|
||||
<string name="referral_point_currencies_title">You</string>
|
||||
<string name="referral_point_currencies_description_prefix">Will get</string>
|
||||
<string name="referral_point_currencies_description_suffix">for each wallet bought by your friend on your Tron network address %s</string>
|
||||
<string name="referral_point_discount_title">Your friend</string>
|
||||
<string name="referral_point_discount_description_prefix">Will get a</string>
|
||||
<string name="referral_point_discount_description_value">%s discount</string>
|
||||
<string name="referral_point_discount_description_suffix">when buying a card on tangem.com</string>
|
||||
<string name="referral_tou_not_enroled_prefix">By tapping this button you accept</string>
|
||||
<string name="common_terms_and_conditions">terms and conditions</string>
|
||||
<string name="referral_tou_suffix">of the referral program</string>
|
||||
<string name="referral_button_participate">Participate</string>
|
||||
<string name="referral_tou_enroled_prefix">You\'ve accepted</string>
|
||||
<string name="referral_promo_code_title">Your personal code</string>
|
||||
<string name="referral_wallets_purchased_count">%d wallets</string>
|
||||
<string name="referral_friends_bought_title">Your friends bought</string>
|
||||
</resources>
|
||||
Loading…
Add table
Add a link
Reference in a new issue