diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/Buttons.kt b/core/ui/src/main/java/com/tangem/core/ui/components/Buttons.kt
index e9e49c5c71..65b331e15c 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/components/Buttons.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/Buttons.kt
@@ -101,6 +101,7 @@ fun Preview_PrimaryEndIconButton_Disabled_InDarkTheme() {
/**
* Primary button with an icon at the beginning of the layout
*
+ * @param modifier button modifier
* @param text button text
* @param iconResId button icon res id
* @param enabled controls the enabled state of the button
@@ -110,8 +111,14 @@ fun Preview_PrimaryEndIconButton_Disabled_InDarkTheme() {
* >Figma component
*/
@Composable
-fun PrimaryStartIconButton(text: String, @DrawableRes iconResId: Int, enabled: Boolean = true, onClicked: () -> Unit) {
- PrimaryButtonRow(enabled = enabled, onClicked = onClicked) {
+fun PrimaryStartIconButton(
+ modifier: Modifier = Modifier,
+ text: String,
+ @DrawableRes iconResId: Int,
+ enabled: Boolean = true,
+ onClicked: () -> Unit,
+) {
+ PrimaryButtonRow(modifier = modifier, enabled = enabled, onClicked = onClicked) {
Icon(
painter = painterResource(id = iconResId),
contentDescription = null,
@@ -124,6 +131,7 @@ fun PrimaryStartIconButton(text: String, @DrawableRes iconResId: Int, enabled: B
/**
* Primary button with an icon at the end of the layout
*
+ * @param modifier button modifier
* @param text button text
* @param iconResId button icon res id
* @param enabled controls the enabled state of the button
@@ -133,8 +141,14 @@ fun PrimaryStartIconButton(text: String, @DrawableRes iconResId: Int, enabled: B
* >Figma component
*/
@Composable
-fun PrimaryEndIconButton(text: String, @DrawableRes iconResId: Int, enabled: Boolean = true, onClicked: () -> Unit) {
- PrimaryButtonRow(enabled = enabled, onClicked = onClicked) {
+fun PrimaryEndIconButton(
+ modifier: Modifier = Modifier,
+ text: String,
+ @DrawableRes iconResId: Int,
+ enabled: Boolean = true,
+ onClicked: () -> Unit,
+) {
+ PrimaryButtonRow(modifier = modifier, enabled = enabled, onClicked = onClicked) {
Text(text = text)
Spacer(modifier = Modifier.width(dimensionResource(R.dimen.spacing8)))
Icon(
@@ -145,10 +159,15 @@ fun PrimaryEndIconButton(text: String, @DrawableRes iconResId: Int, enabled: Boo
}
@Composable
-private fun PrimaryButtonRow(enabled: Boolean, onClicked: () -> Unit, content: @Composable (RowScope.() -> Unit)) {
+private fun PrimaryButtonRow(
+ modifier: Modifier,
+ enabled: Boolean,
+ onClicked: () -> Unit,
+ content: @Composable (RowScope.() -> Unit),
+) {
Button(
onClick = onClicked,
- modifier = Modifier
+ modifier = modifier
.fillMaxWidth()
.height(dimensionResource(R.dimen.size48)),
enabled = enabled,
diff --git a/core/ui/src/main/res/drawable/ic_copy.xml b/core/ui/src/main/res/drawable/ic_copy.xml
new file mode 100644
index 0000000000..d01cdf9823
--- /dev/null
+++ b/core/ui/src/main/res/drawable/ic_copy.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/core/ui/src/main/res/drawable/ic_share.xml b/core/ui/src/main/res/drawable/ic_share.xml
new file mode 100644
index 0000000000..e35c52d223
--- /dev/null
+++ b/core/ui/src/main/res/drawable/ic_share.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/core/ui/src/main/res/values-ru/string_common.xml b/core/ui/src/main/res/values-ru/string_common.xml
new file mode 100644
index 0000000000..ebb5d6b913
--- /dev/null
+++ b/core/ui/src/main/res/values-ru/string_common.xml
@@ -0,0 +1,5 @@
+
+
+ Поделиться
+ Копировать
+
\ No newline at end of file
diff --git a/core/ui/src/main/res/values/string_common.xml b/core/ui/src/main/res/values/string_common.xml
new file mode 100644
index 0000000000..ad2cf0d79f
--- /dev/null
+++ b/core/ui/src/main/res/values/string_common.xml
@@ -0,0 +1,5 @@
+
+
+ Share
+ Copy
+
\ No newline at end of file
diff --git a/features/referral/presentation/src/main/java/com/tangem/feature/referral/ui/AgreementText.kt b/features/referral/presentation/src/main/java/com/tangem/feature/referral/ui/AgreementText.kt
new file mode 100644
index 0000000000..133b6b374e
--- /dev/null
+++ b/features/referral/presentation/src/main/java/com/tangem/feature/referral/ui/AgreementText.kt
@@ -0,0 +1,77 @@
+package com.tangem.feature.referral.ui
+
+import androidx.annotation.StringRes
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.text.ClickableText
+import androidx.compose.material.MaterialTheme
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.dimensionResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.text.AnnotatedString
+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.res.TangemTheme
+import com.tangem.core.ui.res.TextColorType
+import com.tangem.core.ui.res.textColor
+import com.tangem.feature.referral.presentation.R
+
+@Preview(widthDp = 360, showBackground = true)
+@Composable
+fun Preview_AgreementText_InLightTheme() {
+ TangemTheme(isDarkTheme = false) {
+ Box(modifier = Modifier.background(MaterialTheme.colors.primary)) {
+ AgreementText(firstPartResId = R.string.referral_tou_not_enroled_prefix, onClicked = {})
+ }
+ }
+}
+
+@Preview(widthDp = 360, showBackground = true)
+@Composable
+fun Preview_AgreementText_InDarkTheme() {
+ TangemTheme(isDarkTheme = true) {
+ Box(modifier = Modifier.background(MaterialTheme.colors.primary)) {
+ AgreementText(firstPartResId = R.string.referral_tou_not_enroled_prefix, onClicked = {})
+ }
+ }
+}
+
+@Composable
+fun AgreementText(@StringRes firstPartResId: Int, onClicked: () -> Unit) {
+ val agreementText = annotatedAgreementString(firstPart = stringResource(firstPartResId))
+ ClickableText(
+ text = agreementText,
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(horizontal = dimensionResource(id = R.dimen.spacing54)),
+ style = MaterialTheme.typography.caption.copy(textAlign = TextAlign.Center),
+ maxLines = 2,
+ onClick = {
+ val clickableSpanStyle = requireNotNull(agreementText.spanStyles.getOrNull(1))
+ if (it in clickableSpanStyle.start..clickableSpanStyle.end) {
+ onClicked()
+ }
+ },
+ )
+}
+
+@Composable
+private fun annotatedAgreementString(firstPart: String): AnnotatedString {
+ return buildAnnotatedString {
+ withStyle(SpanStyle(color = MaterialTheme.colors.textColor(type = TextColorType.TERTIARY))) {
+ append("$firstPart ")
+ }
+ withStyle(SpanStyle(color = MaterialTheme.colors.textColor(type = TextColorType.ACCENT))) {
+ append(stringResource(id = R.string.common_terms_and_conditions))
+ }
+ withStyle(SpanStyle(color = MaterialTheme.colors.textColor(type = TextColorType.TERTIARY))) {
+ append(" ${stringResource(id = R.string.referral_tou_suffix)}")
+ }
+ }
+}
\ No newline at end of file
diff --git a/features/referral/presentation/src/main/java/com/tangem/feature/referral/ui/NonParticipateBottomBlock.kt b/features/referral/presentation/src/main/java/com/tangem/feature/referral/ui/NonParticipateBottomBlock.kt
new file mode 100644
index 0000000000..59b7ab8148
--- /dev/null
+++ b/features/referral/presentation/src/main/java/com/tangem/feature/referral/ui/NonParticipateBottomBlock.kt
@@ -0,0 +1,139 @@
+package com.tangem.feature.referral.ui
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.shape.RoundedCornerShape
+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.shadow
+import androidx.compose.ui.res.dimensionResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import com.tangem.core.ui.components.PrimaryStartIconButton
+import com.tangem.core.ui.components.SmallInfoCard
+import com.tangem.core.ui.res.TangemTheme
+import com.tangem.core.ui.res.TextColorType
+import com.tangem.core.ui.res.textColor
+import com.tangem.feature.referral.presentation.R
+
+@Preview(widthDp = 360, showBackground = true)
+@Composable
+fun Preview_NonParticipateBottomBlock_InLightTheme() {
+ TangemTheme(isDarkTheme = false) {
+ Column(Modifier.background(MaterialTheme.colors.primary)) {
+ NonParticipateBottomBlock(
+ purchasedWalletCount = 3,
+ code = "x4JdK",
+ onCopyClicked = {},
+ onShareClicked = {},
+ onAgreementClicked = {},
+ )
+ }
+ }
+}
+
+@Preview(widthDp = 360, showBackground = true)
+@Composable
+fun Preview_NonParticipateBottomBlock_InDarkTheme() {
+ TangemTheme(isDarkTheme = true) {
+ Column(Modifier.background(MaterialTheme.colors.primary)) {
+ NonParticipateBottomBlock(
+ purchasedWalletCount = 3,
+ code = "x4JdK",
+ onCopyClicked = {},
+ onShareClicked = {},
+ onAgreementClicked = {},
+ )
+ }
+ }
+}
+
+@Composable
+fun NonParticipateBottomBlock(
+ purchasedWalletCount: Int,
+ code: String,
+ onCopyClicked: () -> Unit,
+ onShareClicked: () -> Unit,
+ onAgreementClicked: () -> Unit,
+) {
+ Column(
+ modifier = Modifier
+ .padding(
+ top = dimensionResource(id = R.dimen.spacing24),
+ bottom = dimensionResource(id = R.dimen.spacing16),
+ )
+ .padding(horizontal = dimensionResource(id = R.dimen.spacing16)),
+ verticalArrangement = Arrangement.spacedBy(dimensionResource(id = R.dimen.spacing16)),
+ ) {
+ SmallInfoCard(
+ startText = stringResource(id = R.string.referral_friends_bought_title),
+ endText = String.format(
+ stringResource(id = R.string.referral_wallets_purchased_count),
+ purchasedWalletCount,
+ ),
+ )
+ PersonalCodeCard(code = code)
+ AdditionalButtons(onCopyClicked = onCopyClicked, onShareClicked = onShareClicked)
+ AgreementText(firstPartResId = R.string.referral_tou_enroled_prefix, onClicked = onAgreementClicked)
+ }
+}
+
+@Composable
+private fun PersonalCodeCard(code: String) {
+ Column(
+ modifier = Modifier
+ .shadow(
+ elevation = dimensionResource(id = R.dimen.elevation2),
+ shape = RoundedCornerShape(dimensionResource(id = R.dimen.radius12)),
+ )
+ .background(
+ color = MaterialTheme.colors.secondary,
+ shape = RoundedCornerShape(dimensionResource(id = R.dimen.radius12)),
+ )
+ .fillMaxWidth()
+ .padding(vertical = dimensionResource(id = R.dimen.spacing12)),
+ horizontalAlignment = Alignment.CenterHorizontally,
+ verticalArrangement = Arrangement.spacedBy(dimensionResource(id = R.dimen.spacing4)),
+ ) {
+ Text(
+ text = stringResource(id = R.string.referral_promo_code_title),
+ color = MaterialTheme.colors.textColor(type = TextColorType.TERTIARY),
+ maxLines = 1,
+ style = MaterialTheme.typography.subtitle2,
+ )
+ Text(
+ text = code,
+ color = MaterialTheme.colors.textColor(type = TextColorType.PRIMARY1),
+ maxLines = 1,
+ style = MaterialTheme.typography.h2,
+ )
+ }
+}
+
+@Composable
+private fun AdditionalButtons(onCopyClicked: () -> Unit, onShareClicked: () -> Unit) {
+ Row(
+ modifier = Modifier.fillMaxWidth(),
+ horizontalArrangement = Arrangement.spacedBy(dimensionResource(id = R.dimen.spacing16)),
+ ) {
+ PrimaryStartIconButton(
+ modifier = Modifier.weight(1f),
+ text = stringResource(id = R.string.common_copy),
+ iconResId = R.drawable.ic_copy,
+ onClicked = onCopyClicked,
+ )
+ PrimaryStartIconButton(
+ modifier = Modifier.weight(1f),
+ text = stringResource(id = R.string.common_share),
+ iconResId = R.drawable.ic_share,
+ onClicked = onShareClicked,
+ )
+ }
+}
\ No newline at end of file
diff --git a/features/referral/presentation/src/main/java/com/tangem/feature/referral/ui/ParticipateBottomBlock.kt b/features/referral/presentation/src/main/java/com/tangem/feature/referral/ui/ParticipateBottomBlock.kt
new file mode 100644
index 0000000000..7294cbd3f7
--- /dev/null
+++ b/features/referral/presentation/src/main/java/com/tangem/feature/referral/ui/ParticipateBottomBlock.kt
@@ -0,0 +1,50 @@
+package com.tangem.feature.referral.ui
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material.MaterialTheme
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.dimensionResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import com.tangem.core.ui.components.PrimaryEndIconButton
+import com.tangem.core.ui.res.TangemTheme
+import com.tangem.feature.referral.presentation.R
+
+@Preview(widthDp = 360, showBackground = true)
+@Composable
+fun Preview_ParticipateBottomBlock_InLightTheme() {
+ TangemTheme(isDarkTheme = false) {
+ Column(Modifier.background(MaterialTheme.colors.primary)) {
+ ParticipateBottomBlock(onAgreementClicked = {}, onParticipateClicked = {})
+ }
+ }
+}
+
+@Preview(widthDp = 360, showBackground = true)
+@Composable
+fun Preview_ParticipateBottomBlock_InDarkTheme() {
+ TangemTheme(isDarkTheme = true) {
+ Column(Modifier.background(MaterialTheme.colors.primary)) {
+ ParticipateBottomBlock(onAgreementClicked = {}, onParticipateClicked = {})
+ }
+ }
+}
+
+@Composable
+fun ParticipateBottomBlock(onAgreementClicked: () -> Unit, onParticipateClicked: () -> Unit) {
+ Column {
+ AgreementText(
+ firstPartResId = R.string.referral_tou_not_enroled_prefix,
+ onClicked = onAgreementClicked,
+ )
+ PrimaryEndIconButton(
+ modifier = Modifier.padding(all = dimensionResource(id = R.dimen.spacing16)),
+ text = stringResource(id = R.string.referral_button_participate),
+ iconResId = R.drawable.ic_tangem,
+ onClicked = onParticipateClicked,
+ )
+ }
+}
\ No newline at end of file
diff --git a/features/referral/presentation/src/main/java/com/tangem/feature/referral/ui/ReferralScreen.kt b/features/referral/presentation/src/main/java/com/tangem/feature/referral/ui/ReferralScreen.kt
index c7894c0bea..46de8b45c4 100644
--- a/features/referral/presentation/src/main/java/com/tangem/feature/referral/ui/ReferralScreen.kt
+++ b/features/referral/presentation/src/main/java/com/tangem/feature/referral/ui/ReferralScreen.kt
@@ -14,7 +14,9 @@ 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.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Icon
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
@@ -167,7 +169,8 @@ fun ReferralScreen(stateHolder: ReferralStateHolder) {
Column(
modifier = Modifier
.background(color = MaterialTheme.colors.primary)
- .fillMaxSize(),
+ .fillMaxSize()
+ .verticalScroll(rememberScrollState()),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Header(stateHolder = stateHolder)
@@ -201,18 +204,20 @@ private fun ColumnScope.Header(stateHolder: ReferralStateHolder) {
@Composable
fun ReferralInfo(stateHolder: ReferralStateHolder) {
when (val state = stateHolder.referralInfoState) {
- is ReferralInfoState.ParticipantContent,
+ is ReferralInfoState.ParticipantContent -> {
+ Conditions(state = state)
+ VerticalSpacer(spaceResId = R.dimen.spacing44)
+ ParticipantBottomBlock(state = state)
+ }
is ReferralInfoState.NonParticipantContent -> {
- Column(verticalArrangement = Arrangement.spacedBy(dimensionResource(id = R.dimen.spacing32))) {
- ConditionForYou(state = state as ReferralStateHolder.ReferralInfoContentState)
- ConditionForYourFriend(state = state)
- }
+ Conditions(state = state)
+ VerticalSpacer(spaceResId = R.dimen.spacing24)
+ NonParticipantBottomBlock(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)
- }
+ LoadingCondition(iconResId = R.drawable.ic_tether)
+ VerticalSpacer(spaceResId = R.dimen.spacing32)
+ LoadingCondition(iconResId = R.drawable.ic_discount)
}
}
}
@@ -225,6 +230,13 @@ private fun AppBar(stateHolder: ReferralStateHolder) {
)
}
+@Composable
+private fun Conditions(state: ReferralStateHolder.ReferralInfoContentState) {
+ ConditionForYou(state = state)
+ VerticalSpacer(spaceResId = R.dimen.spacing32)
+ ConditionForYourFriend(state = state)
+}
+
@Composable
private fun ConditionForYou(state: ReferralStateHolder.ReferralInfoContentState) {
Condition(iconResId = R.drawable.ic_tether) {
@@ -248,7 +260,7 @@ private fun ConditionForYourFriend(state: ReferralStateHolder.ReferralInfoConten
@Composable
private fun LoadingCondition(@DrawableRes iconResId: Int) {
Condition(iconResId = iconResId) {
- ShimmerCondition()
+ ShimmerInfo()
}
}
@@ -335,7 +347,7 @@ private fun ConditionInfo(title: String, subtitleContent: @Composable () -> Unit
}
@Composable
-private fun ShimmerCondition() {
+private fun ShimmerInfo() {
Column(
modifier = Modifier
.fillMaxWidth()
@@ -360,3 +372,22 @@ private fun ShimmerCondition() {
}
}
+@Composable
+private fun ParticipantBottomBlock(state: ReferralInfoState.ParticipantContent) {
+ ParticipateBottomBlock(
+ onAgreementClicked = state.onAgreementClicked,
+ onParticipateClicked = state.onParticipateClicked,
+ )
+}
+
+@Composable
+private fun NonParticipantBottomBlock(state: ReferralInfoState.NonParticipantContent) {
+ NonParticipateBottomBlock(
+ purchasedWalletCount = state.purchasedWalletCount,
+ code = state.code,
+ onCopyClicked = state.onCopyClicked,
+ onShareClicked = state.onShareClicked,
+ onAgreementClicked = state.onAgreementClicked,
+ )
+}
+