diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/Spacers.kt b/core/ui/src/main/java/com/tangem/core/ui/components/Spacers.kt
index 99230c1853..131ca91e00 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/components/Spacers.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/Spacers.kt
@@ -14,6 +14,11 @@ fun SpacerH(height: Dp, modifier: Modifier = Modifier) {
Spacer(modifier = modifier.height(height))
}
+@Composable
+fun SpacerH2(modifier: Modifier = Modifier) {
+ SpacerH(2.dp, modifier)
+}
+
@Composable
fun SpacerH4(modifier: Modifier = Modifier) {
SpacerH(4.dp, modifier)
diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/components/UnableToLoadData.kt b/core/ui/src/main/java/com/tangem/core/ui/components/UnableToLoadData.kt
similarity index 88%
rename from features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/components/UnableToLoadData.kt
rename to core/ui/src/main/java/com/tangem/core/ui/components/UnableToLoadData.kt
index c96d848bac..19f8e5fcbd 100644
--- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/components/UnableToLoadData.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/UnableToLoadData.kt
@@ -1,4 +1,4 @@
-package com.tangem.features.markets.tokenlist.impl.ui.components
+package com.tangem.core.ui.components
import android.content.res.Configuration
import androidx.compose.foundation.layout.Arrangement
@@ -8,16 +8,16 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
+import com.tangem.core.ui.R
import com.tangem.core.ui.components.buttons.SecondarySmallButton
import com.tangem.core.ui.components.buttons.SmallButtonConfig
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.features.markets.impl.R
@Composable
-internal fun UnableToLoadData(onRetryClick: () -> Unit, modifier: Modifier = Modifier) {
+fun UnableToLoadData(onRetryClick: () -> Unit, modifier: Modifier = Modifier) {
Column(
modifier = modifier,
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12),
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/currency/icon/CurrencyIcon.kt b/core/ui/src/main/java/com/tangem/core/ui/components/currency/icon/CurrencyIcon.kt
index a9a7677136..4727ba9759 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/components/currency/icon/CurrencyIcon.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/currency/icon/CurrencyIcon.kt
@@ -109,7 +109,7 @@ private fun BoxScope.ContentIconContainer(
)
if (icon.topBadgeIconResId != null && shouldShowTopBadge) {
- TopBadge(
+ CurrencyIconTopBadge(
modifier = Modifier
.offset(x = networkBadgeOffset, y = -networkBadgeOffset)
.align(Alignment.TopEnd),
@@ -120,7 +120,7 @@ private fun BoxScope.ContentIconContainer(
}
if (icon.showCustomBadge) {
- BottomBadge(
+ CurrencyIconBottomBadge(
modifier = Modifier.align(Alignment.BottomEnd),
)
}
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/currency/icon/CurrencyIconIconBadge.kt b/core/ui/src/main/java/com/tangem/core/ui/components/currency/icon/CurrencyIconIconBadge.kt
new file mode 100644
index 0000000000..b074076629
--- /dev/null
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/currency/icon/CurrencyIconIconBadge.kt
@@ -0,0 +1,32 @@
+package com.tangem.core.ui.components.currency.icon
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.shape.CircleShape
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import com.tangem.core.ui.res.TangemTheme
+
+@Composable
+internal fun CurrencyIconBottomBadge(modifier: Modifier = Modifier) {
+ Box(
+ modifier = modifier
+ .size(TangemTheme.dimens.size12)
+ .background(
+ color = TangemTheme.colors.background.primary,
+ shape = CircleShape,
+ ),
+ ) {
+ Box(
+ modifier = Modifier
+ .padding(all = TangemTheme.dimens.spacing2)
+ .matchParentSize()
+ .background(
+ color = TangemTheme.colors.icon.informative,
+ shape = CircleShape,
+ ),
+ )
+ }
+}
\ No newline at end of file
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/currency/icon/IconBadge.kt b/core/ui/src/main/java/com/tangem/core/ui/components/currency/icon/CurrencyIconTopBadge.kt
similarity index 66%
rename from core/ui/src/main/java/com/tangem/core/ui/components/currency/icon/IconBadge.kt
rename to core/ui/src/main/java/com/tangem/core/ui/components/currency/icon/CurrencyIconTopBadge.kt
index 09e597f7a6..03057d495d 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/components/currency/icon/IconBadge.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/currency/icon/CurrencyIconTopBadge.kt
@@ -14,7 +14,7 @@ import androidx.compose.ui.res.painterResource
import com.tangem.core.ui.res.TangemTheme
@Composable
-internal fun TopBadge(
+fun CurrencyIconTopBadge(
@DrawableRes iconResId: Int,
alpha: Float,
colorFilter: ColorFilter?,
@@ -38,26 +38,4 @@ internal fun TopBadge(
contentDescription = null,
)
}
-}
-
-@Composable
-internal fun BottomBadge(modifier: Modifier = Modifier) {
- Box(
- modifier = modifier
- .size(TangemTheme.dimens.size12)
- .background(
- color = TangemTheme.colors.background.primary,
- shape = CircleShape,
- ),
- ) {
- Box(
- modifier = Modifier
- .padding(all = TangemTheme.dimens.spacing2)
- .matchParentSize()
- .background(
- color = TangemTheme.colors.icon.informative,
- shape = CircleShape,
- ),
- )
- }
}
\ No newline at end of file
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/fields/SearchBar.kt b/core/ui/src/main/java/com/tangem/core/ui/components/fields/SearchBar.kt
index 9863c30ba0..d69616e5d6 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/components/fields/SearchBar.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/fields/SearchBar.kt
@@ -11,6 +11,7 @@ import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.Stable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusManager
@@ -36,7 +37,11 @@ import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
@Composable
-fun SearchBar(state: SearchBarUM, modifier: Modifier = Modifier, colors: TextFieldColors = TangemSearchBarColors) {
+fun SearchBar(
+ state: SearchBarUM,
+ modifier: Modifier = Modifier,
+ colors: TextFieldColors = TangemSearchBarDefaults.defaultTextFieldColors,
+) {
val keyboardController = LocalSoftwareKeyboardController.current
val focusManager = LocalFocusManager.current
val interactionSource = remember { MutableInteractionSource() }
@@ -161,18 +166,30 @@ private fun ClearButton(
}
}
-private val TangemSearchBarColors: TextFieldColors
- @Composable
- get() = TextFieldDefaults.colors().copy(
- focusedContainerColor = TangemTheme.colors.field.primary,
- unfocusedContainerColor = TangemTheme.colors.field.primary,
- focusedTextColor = TangemTheme.colors.text.primary1,
- unfocusedTextColor = TangemTheme.colors.text.primary1,
- cursorColor = TangemTheme.colors.icon.primary1,
- focusedIndicatorColor = Color.Transparent,
- unfocusedIndicatorColor = Color.Transparent,
- disabledIndicatorColor = Color.Transparent,
- )
+object TangemSearchBarDefaults {
+ val defaultTextFieldColors: TextFieldColors
+ @Composable @Stable get() = TextFieldDefaults.colors().copy(
+ focusedContainerColor = TangemTheme.colors.field.primary,
+ unfocusedContainerColor = TangemTheme.colors.field.primary,
+ focusedTextColor = TangemTheme.colors.text.primary1,
+ unfocusedTextColor = TangemTheme.colors.text.primary1,
+ cursorColor = TangemTheme.colors.icon.primary1,
+ focusedIndicatorColor = Color.Transparent,
+ unfocusedIndicatorColor = Color.Transparent,
+ disabledIndicatorColor = Color.Transparent,
+ )
+ val secondaryTextFieldColors: TextFieldColors
+ @Composable @Stable get() = TextFieldDefaults.colors().copy(
+ focusedContainerColor = TangemTheme.colors.field.focused,
+ unfocusedContainerColor = TangemTheme.colors.field.focused,
+ focusedTextColor = TangemTheme.colors.text.primary1,
+ unfocusedTextColor = TangemTheme.colors.text.primary1,
+ cursorColor = TangemTheme.colors.icon.primary1,
+ focusedIndicatorColor = Color.Transparent,
+ unfocusedIndicatorColor = Color.Transparent,
+ disabledIndicatorColor = Color.Transparent,
+ )
+}
// region Previews
@Preview(widthDp = 328)
diff --git a/core/ui/src/main/res/drawable/ic_nft_placeholder_76.xml b/core/ui/src/main/res/drawable/ic_nft_placeholder_76.xml
new file mode 100644
index 0000000000..6e6a840d1f
--- /dev/null
+++ b/core/ui/src/main/res/drawable/ic_nft_placeholder_76.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/ui/components/MarketTokenDetailsChart.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/ui/components/MarketTokenDetailsChart.kt
index 39970e9671..076b704bb8 100644
--- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/ui/components/MarketTokenDetailsChart.kt
+++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/ui/components/MarketTokenDetailsChart.kt
@@ -16,7 +16,7 @@ import com.tangem.common.ui.charts.state.MarketChartLook
import com.tangem.common.ui.charts.state.rememberMarketChartState
import com.tangem.core.ui.res.TangemTheme
import com.tangem.features.markets.details.impl.ui.state.MarketsTokenDetailsUM
-import com.tangem.features.markets.tokenlist.impl.ui.components.UnableToLoadData
+import com.tangem.core.ui.components.UnableToLoadData
@Composable
internal fun MarketTokenDetailsChart(
diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/ui/components/TokenMarketDetailsBody.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/ui/components/TokenMarketDetailsBody.kt
index 0d04d56bbe..b796c0f38a 100644
--- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/ui/components/TokenMarketDetailsBody.kt
+++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/ui/components/TokenMarketDetailsBody.kt
@@ -9,7 +9,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import com.tangem.core.ui.res.TangemTheme
import com.tangem.features.markets.details.impl.ui.state.MarketsTokenDetailsUM
-import com.tangem.features.markets.tokenlist.impl.ui.components.UnableToLoadData
+import com.tangem.core.ui.components.UnableToLoadData
internal fun LazyListScope.tokenMarketDetailsBody(
state: MarketsTokenDetailsUM.Body,
diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/components/MarketsListLazyColumn.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/components/MarketsListLazyColumn.kt
index 703e2eae67..6fcc3b1195 100644
--- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/components/MarketsListLazyColumn.kt
+++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/components/MarketsListLazyColumn.kt
@@ -10,6 +10,7 @@ import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalDensity
+import com.tangem.core.ui.components.UnableToLoadData
import com.tangem.core.ui.components.buttons.SecondarySmallButton
import com.tangem.core.ui.components.buttons.SmallButtonConfig
import com.tangem.core.ui.components.list.InfiniteListHandler
diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/entity/NFTCollectionAssetUM.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/entity/NFTCollectionAssetUM.kt
new file mode 100644
index 0000000000..fc75d29651
--- /dev/null
+++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/entity/NFTCollectionAssetUM.kt
@@ -0,0 +1,9 @@
+package com.tangem.features.nft.collections.entity
+
+internal data class NFTCollectionAssetUM(
+ val id: String,
+ val name: String,
+ val imageUrl: String?,
+ val price: NFTSalePriceUM,
+ val onItemClick: () -> Unit,
+)
\ No newline at end of file
diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/entity/NFTCollectionAssetsListUM.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/entity/NFTCollectionAssetsListUM.kt
new file mode 100644
index 0000000000..7b0147b03a
--- /dev/null
+++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/entity/NFTCollectionAssetsListUM.kt
@@ -0,0 +1,16 @@
+package com.tangem.features.nft.collections.entity
+
+import androidx.compose.runtime.Immutable
+import kotlinx.collections.immutable.ImmutableList
+
+@Immutable
+internal sealed class NFTCollectionAssetsListUM {
+ data object Collapsed : NFTCollectionAssetsListUM()
+
+ @Immutable
+ sealed class Expanded : NFTCollectionAssetsListUM() {
+ data class Loading(val itemsCount: Int) : Expanded()
+ data class Failed(val onRetryClick: () -> Unit) : Expanded()
+ data class Content(val items: ImmutableList) : Expanded()
+ }
+}
\ No newline at end of file
diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/entity/NFTCollectionUM.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/entity/NFTCollectionUM.kt
new file mode 100644
index 0000000000..8e3375906b
--- /dev/null
+++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/entity/NFTCollectionUM.kt
@@ -0,0 +1,14 @@
+package com.tangem.features.nft.collections.entity
+
+import androidx.annotation.DrawableRes
+import com.tangem.core.ui.extensions.TextReference
+
+internal data class NFTCollectionUM(
+ val id: String,
+ val name: String,
+ @DrawableRes val networkIconId: Int,
+ val logoUrl: String?,
+ val description: TextReference,
+ val assets: NFTCollectionAssetsListUM,
+ val onExpandClick: () -> Unit,
+)
\ No newline at end of file
diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/entity/NFTCollectionsUM.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/entity/NFTCollectionsUM.kt
new file mode 100644
index 0000000000..394144b65d
--- /dev/null
+++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/entity/NFTCollectionsUM.kt
@@ -0,0 +1,29 @@
+package com.tangem.features.nft.collections.entity
+
+import androidx.compose.runtime.Immutable
+import com.tangem.core.ui.components.fields.entity.SearchBarUM
+import kotlinx.collections.immutable.ImmutableList
+
+@Immutable
+internal sealed class NFTCollectionsUM {
+
+ data class Empty(
+ val onReceiveClick: () -> Unit,
+ ) : NFTCollectionsUM()
+
+ data class Loading(
+ val onReceiveClick: () -> Unit,
+ ) : NFTCollectionsUM()
+
+ data class Failed(
+ val onRetryClick: () -> Unit,
+ val onReceiveClick: () -> Unit,
+ ) : NFTCollectionsUM()
+
+ data class Content(
+ val search: SearchBarUM,
+ val collections: ImmutableList,
+ val warnings: ImmutableList,
+ val onReceiveClick: () -> Unit,
+ ) : NFTCollectionsUM()
+}
\ No newline at end of file
diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/entity/NFTCollectionsWarningUM.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/entity/NFTCollectionsWarningUM.kt
new file mode 100644
index 0000000000..f0bdc22aaa
--- /dev/null
+++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/entity/NFTCollectionsWarningUM.kt
@@ -0,0 +1,5 @@
+package com.tangem.features.nft.collections.entity
+
+import com.tangem.core.ui.components.notifications.NotificationConfig
+
+internal data class NFTCollectionsWarningUM(val config: NotificationConfig)
\ No newline at end of file
diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/entity/NFTSalePriceUM.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/entity/NFTSalePriceUM.kt
new file mode 100644
index 0000000000..8747a49f55
--- /dev/null
+++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/entity/NFTSalePriceUM.kt
@@ -0,0 +1,10 @@
+package com.tangem.features.nft.collections.entity
+
+import androidx.compose.runtime.Immutable
+
+@Immutable
+internal sealed class NFTSalePriceUM {
+ data object Loading : NFTSalePriceUM()
+ data object Failed : NFTSalePriceUM()
+ data class Content(val price: String) : NFTSalePriceUM()
+}
\ No newline at end of file
diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTCollection.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTCollection.kt
new file mode 100644
index 0000000000..32f7159f78
--- /dev/null
+++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTCollection.kt
@@ -0,0 +1,178 @@
+package com.tangem.features.nft.collections.ui
+
+import android.content.res.Configuration
+import androidx.compose.animation.core.animateFloatAsState
+import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.*
+import androidx.compose.material3.Icon
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.draw.rotate
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.tooling.preview.PreviewParameter
+import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
+import coil.compose.SubcomposeAsyncImage
+import com.tangem.core.ui.components.RectangleShimmer
+import com.tangem.core.ui.components.currency.icon.CurrencyIconTopBadge
+import com.tangem.core.ui.extensions.TextReference
+import com.tangem.core.ui.extensions.resolveReference
+import com.tangem.core.ui.res.TangemTheme
+import com.tangem.core.ui.res.TangemThemePreview
+import com.tangem.features.nft.collections.entity.NFTCollectionAssetsListUM
+import com.tangem.features.nft.collections.entity.NFTCollectionUM
+import com.tangem.features.nft.impl.R
+
+private const val CHEVRON_ROTATION_EXPANDED = 180f
+private const val CHEVRON_ROTATION_COLLAPSED = 0f
+
+@Composable
+internal fun NFTCollection(state: NFTCollectionUM, modifier: Modifier = Modifier) {
+ val isExpanded = state.assets is NFTCollectionAssetsListUM.Expanded
+
+ Column(
+ modifier = modifier,
+ ) {
+ Row(
+ modifier = Modifier
+ .clickable(onClick = state.onExpandClick)
+ .padding(
+ vertical = TangemTheme.dimens.spacing16,
+ horizontal = TangemTheme.dimens.spacing12,
+ ),
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ Logo(state)
+
+ Text(state)
+
+ val rotation by animateFloatAsState(
+ targetValue = if (isExpanded) {
+ CHEVRON_ROTATION_EXPANDED
+ } else {
+ CHEVRON_ROTATION_COLLAPSED
+ },
+ label = "chevron_rotation",
+ )
+
+ Icon(
+ modifier = Modifier
+ .rotate(rotation)
+ .size(TangemTheme.dimens.size24),
+ painter = painterResource(id = R.drawable.ic_chevron_24),
+ tint = if (isExpanded) {
+ TangemTheme.colors.icon.primary1
+ } else {
+ TangemTheme.colors.icon.inactive
+ },
+ contentDescription = null,
+ )
+ }
+ }
+}
+
+@Composable
+private fun Logo(state: NFTCollectionUM) {
+ val networkBadgeOffset = TangemTheme.dimens.spacing6
+
+ Box(
+ modifier = Modifier,
+ ) {
+ SubcomposeAsyncImage(
+ modifier = Modifier
+ .align(Alignment.CenterStart)
+ .size(TangemTheme.dimens.size36),
+ model = state.logoUrl,
+ loading = {
+ RectangleShimmer(radius = TangemTheme.dimens.radius8)
+ },
+ error = {
+ Box(
+ modifier = Modifier
+ .clip(shape = TangemTheme.shapes.roundedCorners8)
+ .background(TangemTheme.colors.field.primary),
+ )
+ },
+ contentDescription = null,
+ )
+ CurrencyIconTopBadge(
+ modifier = Modifier
+ .offset(x = networkBadgeOffset, y = -networkBadgeOffset)
+ .align(Alignment.TopEnd),
+ iconResId = state.networkIconId,
+ alpha = 1f,
+ colorFilter = null,
+ )
+ }
+}
+
+@Composable
+private fun RowScope.Text(state: NFTCollectionUM) {
+ Column(
+ modifier = Modifier
+ .weight(1f)
+ .padding(
+ horizontal = TangemTheme.dimens.spacing12,
+ ),
+ ) {
+ Text(
+ modifier = Modifier,
+ text = state.name,
+ style = TangemTheme.typography.subtitle2,
+ color = TangemTheme.colors.text.primary1,
+ maxLines = 1,
+ overflow = TextOverflow.Ellipsis,
+ )
+ Text(
+ modifier = Modifier
+ .padding(top = TangemTheme.dimens.spacing2),
+ text = state.description.resolveReference(),
+ style = TangemTheme.typography.caption2,
+ color = TangemTheme.colors.text.tertiary,
+ maxLines = 1,
+ overflow = TextOverflow.Ellipsis,
+ )
+ }
+}
+
+@Preview(widthDp = 360, showBackground = true)
+@Preview(widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
+@Composable
+private fun Preview_NFTCollection(@PreviewParameter(NFTCollectionProvider::class) item: NFTCollectionUM) {
+ TangemThemePreview {
+ NFTCollection(
+ state = item,
+ )
+ }
+}
+
+private class NFTCollectionProvider : CollectionPreviewParameterProvider(
+ collection = listOf(
+ NFTCollectionUM(
+ id = "item1",
+ name = "Nethers",
+ logoUrl = "",
+ networkIconId = R.drawable.img_eth_22,
+ description = TextReference.Str("3 items"),
+ assets = NFTCollectionAssetsListUM.Collapsed,
+ onExpandClick = { },
+ ),
+ NFTCollectionUM(
+ id = "item2",
+ name = "Nethers",
+ logoUrl = "",
+ networkIconId = R.drawable.img_eth_22,
+ description = TextReference.Str("3 items"),
+ assets = NFTCollectionAssetsListUM.Expanded.Loading(
+ itemsCount = 3,
+ ),
+ onExpandClick = { },
+ ),
+ ),
+)
\ No newline at end of file
diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTCollectionAsset.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTCollectionAsset.kt
new file mode 100644
index 0000000000..9951cd16a7
--- /dev/null
+++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTCollectionAsset.kt
@@ -0,0 +1,100 @@
+package com.tangem.features.nft.collections.ui
+
+import android.content.res.Configuration
+import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.aspectRatio
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.tooling.preview.PreviewParameter
+import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
+import coil.compose.SubcomposeAsyncImage
+import com.tangem.core.ui.components.RectangleShimmer
+import com.tangem.core.ui.components.SpacerH12
+import com.tangem.core.ui.components.SpacerH2
+import com.tangem.core.ui.res.TangemTheme
+import com.tangem.core.ui.res.TangemThemePreview
+import com.tangem.features.nft.collections.entity.NFTCollectionAssetUM
+import com.tangem.features.nft.collections.entity.NFTSalePriceUM
+
+@Composable
+internal fun NFTCollectionAsset(state: NFTCollectionAssetUM, modifier: Modifier = Modifier) {
+ Column(
+ modifier = modifier
+ .clickable { state.onItemClick() },
+ ) {
+ SubcomposeAsyncImage(
+ modifier = Modifier
+ .aspectRatio(1f),
+ model = state.imageUrl,
+ loading = {
+ RectangleShimmer(radius = TangemTheme.dimens.radius16)
+ },
+ error = {
+ Box(
+ modifier = Modifier
+ .clip(shape = TangemTheme.shapes.roundedCornersXMedium)
+ .background(TangemTheme.colors.field.primary),
+ )
+ },
+ contentDescription = null,
+ )
+ SpacerH12()
+ Text(
+ text = state.name,
+ style = TangemTheme.typography.subtitle2,
+ color = TangemTheme.colors.text.primary1,
+ maxLines = 1,
+ overflow = TextOverflow.Ellipsis,
+ )
+ SpacerH2()
+ NFTSalePrice(
+ state = state.price,
+ )
+ }
+}
+
+@Preview(widthDp = 180, showBackground = true)
+@Preview(widthDp = 180, uiMode = Configuration.UI_MODE_NIGHT_YES)
+@Composable
+private fun Preview_NFTCollectionAsset(
+ @PreviewParameter(NFTCollectionAssetProvider::class) state: NFTCollectionAssetUM,
+) {
+ TangemThemePreview {
+ NFTCollectionAsset(
+ state = state,
+ )
+ }
+}
+
+private class NFTCollectionAssetProvider : CollectionPreviewParameterProvider(
+ collection = listOf(
+ NFTCollectionAssetUM(
+ id = "item1",
+ name = "Nethers #0853",
+ imageUrl = "img",
+ price = NFTSalePriceUM.Loading,
+ onItemClick = { },
+ ),
+ NFTCollectionAssetUM(
+ id = "item2",
+ name = "Nethers #0854",
+ imageUrl = "img",
+ price = NFTSalePriceUM.Failed,
+ onItemClick = { },
+ ),
+ NFTCollectionAssetUM(
+ id = "item3",
+ name = "Nethers #0855",
+ imageUrl = "img",
+ price = NFTSalePriceUM.Content("0.05 ETH"),
+ onItemClick = { },
+ ),
+ ),
+)
\ No newline at end of file
diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTCollectionAssetLoading.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTCollectionAssetLoading.kt
new file mode 100644
index 0000000000..66bf216ad7
--- /dev/null
+++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTCollectionAssetLoading.kt
@@ -0,0 +1,47 @@
+package com.tangem.features.nft.collections.ui
+
+import android.content.res.Configuration
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.aspectRatio
+import androidx.compose.foundation.layout.width
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.tooling.preview.Preview
+import com.tangem.core.ui.components.*
+import com.tangem.core.ui.res.TangemTheme
+import com.tangem.core.ui.res.TangemThemePreview
+
+@Composable
+internal fun NFTCollectionAssetLoading(modifier: Modifier = Modifier) {
+ Column(
+ modifier = modifier,
+ ) {
+ RectangleShimmer(
+ modifier = Modifier
+ .aspectRatio(1f),
+ )
+ SpacerH12()
+ TextShimmer(
+ modifier = Modifier
+ .width(TangemTheme.dimens.size86),
+ style = TangemTheme.typography.subtitle2,
+ textSizeHeight = true,
+ )
+ SpacerH2()
+ TextShimmer(
+ modifier = Modifier
+ .width(TangemTheme.dimens.size48),
+ style = TangemTheme.typography.caption2,
+ textSizeHeight = true,
+ )
+ }
+}
+
+@Preview(widthDp = 180, showBackground = true)
+@Preview(widthDp = 180, uiMode = Configuration.UI_MODE_NIGHT_YES)
+@Composable
+private fun Preview_NFTCollectionAsset() {
+ TangemThemePreview {
+ NFTCollectionAssetLoading()
+ }
+}
\ No newline at end of file
diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTCollectionWarning.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTCollectionWarning.kt
new file mode 100644
index 0000000000..337e675026
--- /dev/null
+++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTCollectionWarning.kt
@@ -0,0 +1,14 @@
+package com.tangem.features.nft.collections.ui
+
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import com.tangem.core.ui.components.notifications.Notification
+import com.tangem.features.nft.collections.entity.NFTCollectionsWarningUM
+
+@Composable
+internal fun NFTCollectionWarning(state: NFTCollectionsWarningUM, modifier: Modifier = Modifier) {
+ Notification(
+ modifier = modifier,
+ config = state.config,
+ )
+}
\ No newline at end of file
diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTCollectionsContent.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTCollectionsContent.kt
new file mode 100644
index 0000000000..6a1b002cf4
--- /dev/null
+++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTCollectionsContent.kt
@@ -0,0 +1,318 @@
+package com.tangem.features.nft.collections.ui
+
+import android.content.res.Configuration
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.LazyListScope
+import androidx.compose.foundation.lazy.rememberLazyListState
+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.tooling.preview.Preview
+import androidx.compose.ui.util.fastForEach
+import com.tangem.core.ui.components.PrimaryButton
+import com.tangem.core.ui.components.UnableToLoadData
+import com.tangem.core.ui.components.fields.SearchBar
+import com.tangem.core.ui.components.fields.TangemSearchBarDefaults
+import com.tangem.core.ui.components.fields.entity.SearchBarUM
+import com.tangem.core.ui.components.notifications.NotificationConfig
+import com.tangem.core.ui.extensions.TextReference
+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.features.nft.collections.entity.*
+import com.tangem.features.nft.collections.entity.NFTCollectionAssetUM
+import com.tangem.features.nft.collections.entity.NFTCollectionAssetsListUM
+import com.tangem.features.nft.collections.entity.NFTCollectionUM
+import com.tangem.features.nft.collections.entity.NFTCollectionsUM
+import com.tangem.features.nft.collections.entity.NFTSalePriceUM
+import com.tangem.features.nft.impl.R
+import kotlinx.collections.immutable.persistentListOf
+
+@Suppress("LongMethod")
+@Composable
+internal fun NFTCollectionsContent(state: NFTCollectionsUM.Content, modifier: Modifier = Modifier) {
+ val listState = rememberLazyListState()
+
+ Box(
+ modifier = modifier
+ .fillMaxSize()
+ .background(TangemTheme.colors.background.secondary)
+ .padding(
+ start = TangemTheme.dimens.spacing16,
+ end = TangemTheme.dimens.spacing16,
+ bottom = TangemTheme.dimens.spacing16,
+ ),
+ ) {
+ Column(
+ modifier = Modifier,
+ ) {
+ SearchBar(
+ state = state.search,
+ colors = TangemSearchBarDefaults.secondaryTextFieldColors,
+ )
+ state.warnings.fastForEach {
+ NFTCollectionWarning(
+ modifier = Modifier
+ .padding(top = TangemTheme.dimens.spacing16),
+ state = it,
+ )
+ }
+ LazyColumn(
+ modifier = Modifier
+ .padding(
+ top = TangemTheme.dimens.spacing16,
+ )
+ .clip(TangemTheme.shapes.roundedCornersXMedium)
+ .background(TangemTheme.colors.background.primary),
+ state = listState,
+ ) {
+ state.collections.fastForEach { collection ->
+ item(key = collection.id) {
+ NFTCollection(
+ modifier = Modifier.fillMaxWidth(),
+ state = collection,
+ )
+ }
+ when (val assets = collection.assets) {
+ is NFTCollectionAssetsListUM.Collapsed -> Unit
+ is NFTCollectionAssetsListUM.Expanded.Loading -> {
+ assetsListLoading(
+ collectionId = collection.id,
+ content = assets,
+ )
+ }
+ is NFTCollectionAssetsListUM.Expanded.Failed -> {
+ assetsListFailed(
+ collectionId = collection.id,
+ content = assets,
+ )
+ }
+ is NFTCollectionAssetsListUM.Expanded.Content -> {
+ assetsListContent(
+ collectionId = collection.id,
+ content = assets,
+ )
+ }
+ }
+ }
+ }
+ }
+ PrimaryButton(
+ modifier = Modifier
+ .fillMaxWidth()
+ .align(Alignment.BottomCenter),
+ text = stringResourceSafe(R.string.nft_collections_receive),
+ onClick = { },
+ )
+ }
+}
+
+private fun LazyListScope.assetsListLoading(
+ collectionId: String,
+ content: NFTCollectionAssetsListUM.Expanded.Loading,
+) {
+ val itemsCount = content.itemsCount
+ val rowCount = (itemsCount + 1) / 2
+ repeat(rowCount) { rowIndex ->
+ item(
+ key = "loading_${collectionId}_$rowIndex",
+ ) {
+ val paddingValues = PaddingValues(
+ start = TangemTheme.dimens.spacing6,
+ top = TangemTheme.dimens.spacing6,
+ end = TangemTheme.dimens.spacing6,
+ bottom = TangemTheme.dimens.spacing20,
+ )
+ Row(
+ modifier = Modifier
+ .padding(TangemTheme.dimens.spacing6)
+ .animateItem(),
+ ) {
+ NFTCollectionAssetLoading(
+ modifier = Modifier
+ .weight(1f)
+ .padding(paddingValues),
+ )
+ if (rowIndex == rowCount - 1 && itemsCount % 2 != 0) {
+ Box(
+ modifier = Modifier
+ .weight(1f)
+ .padding(paddingValues),
+ )
+ } else {
+ NFTCollectionAssetLoading(
+ modifier = Modifier
+ .weight(1f)
+ .padding(paddingValues),
+ )
+ }
+ }
+ }
+ }
+}
+
+private fun LazyListScope.assetsListFailed(collectionId: String, content: NFTCollectionAssetsListUM.Expanded.Failed) {
+ item(
+ key = "failed_$collectionId",
+ ) {
+ Box(
+ modifier = Modifier
+ .fillMaxWidth()
+ .height(TangemTheme.dimens.size142),
+ contentAlignment = Alignment.Center,
+ ) {
+ UnableToLoadData(
+ onRetryClick = content.onRetryClick,
+ )
+ }
+ }
+}
+
+private fun LazyListScope.assetsListContent(
+ collectionId: String,
+ content: NFTCollectionAssetsListUM.Expanded.Content,
+) {
+ val items = content.items
+ val itemsCount = items.size
+ val rowCount = (itemsCount + 1) / 2
+ repeat(rowCount) { rowIndex ->
+ val item1 = items[rowIndex * 2]
+ val item2 = items.getOrNull(rowIndex * 2 + 1)
+ item(
+ key = "content_${collectionId}_${item1.id}_${item2?.id}",
+ ) {
+ val paddingValues = PaddingValues(
+ start = TangemTheme.dimens.spacing6,
+ top = TangemTheme.dimens.spacing6,
+ end = TangemTheme.dimens.spacing6,
+ bottom = TangemTheme.dimens.spacing20,
+ )
+ Row(
+ modifier = Modifier
+ .padding(TangemTheme.dimens.spacing6)
+ .animateItem(),
+ ) {
+ NFTCollectionAsset(
+ modifier = Modifier
+ .weight(1f)
+ .padding(paddingValues),
+ state = item1,
+ )
+ if (item2 == null) {
+ Box(
+ modifier = Modifier
+ .weight(1f)
+ .padding(paddingValues),
+ )
+ } else {
+ NFTCollectionAsset(
+ modifier = Modifier
+ .weight(1f)
+ .padding(paddingValues),
+ state = item2,
+ )
+ }
+ }
+ }
+ }
+}
+
+@Suppress("LongMethod")
+@Preview(widthDp = 360, showBackground = true)
+@Preview(widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
+@Composable
+private fun Preview_NFTCollectionsContent() {
+ TangemThemePreview {
+ NFTCollectionsContent(
+ state = NFTCollectionsUM.Content(
+ search = SearchBarUM(
+ placeholderText = resourceReference(R.string.common_search),
+ query = "",
+ onQueryChange = {},
+ isActive = false,
+ onActiveChange = { },
+ ),
+ collections = persistentListOf(
+ NFTCollectionUM(
+ id = "item1",
+ name = "Nethers",
+ logoUrl = "",
+ networkIconId = R.drawable.img_eth_22,
+ description = TextReference.Str("3 items"),
+ assets = NFTCollectionAssetsListUM.Collapsed,
+ onExpandClick = { },
+ ),
+ NFTCollectionUM(
+ id = "item2",
+ name = "Nethers",
+ logoUrl = "",
+ networkIconId = R.drawable.img_eth_22,
+ description = TextReference.Str("3 items"),
+ assets = NFTCollectionAssetsListUM.Expanded.Loading(
+ itemsCount = 1,
+ ),
+ onExpandClick = { },
+ ),
+ NFTCollectionUM(
+ id = "item3",
+ name = "Nethers",
+ logoUrl = "",
+ networkIconId = R.drawable.img_eth_22,
+ description = TextReference.Str("3 items"),
+ assets = NFTCollectionAssetsListUM.Expanded.Failed(
+ onRetryClick = { },
+ ),
+ onExpandClick = { },
+ ),
+ NFTCollectionUM(
+ id = "item4",
+ name = "Nethers",
+ logoUrl = "",
+ networkIconId = R.drawable.img_eth_22,
+ description = TextReference.Str("3 items"),
+ assets = NFTCollectionAssetsListUM.Expanded.Content(
+ items = persistentListOf(
+ NFTCollectionAssetUM(
+ id = "item1",
+ name = "Nethers #0854",
+ imageUrl = "img",
+ price = NFTSalePriceUM.Content("0.05 ETH"),
+ onItemClick = { },
+ ),
+ NFTCollectionAssetUM(
+ id = "item2",
+ name = "Nethers #0855",
+ imageUrl = "img",
+ price = NFTSalePriceUM.Loading,
+ onItemClick = { },
+ ),
+ NFTCollectionAssetUM(
+ id = "item3",
+ name = "Nethers #0856",
+ imageUrl = "img",
+ price = NFTSalePriceUM.Failed,
+ onItemClick = { },
+ ),
+ ),
+ ),
+ onExpandClick = { },
+ ),
+ ),
+ warnings = persistentListOf(
+ NFTCollectionsWarningUM(
+ config = NotificationConfig(
+ title = TextReference.Res(R.string.nft_collections_warning_title),
+ subtitle = TextReference.Res(R.string.nft_collections_warning_subtitle),
+ iconResId = R.drawable.ic_alert_triangle_20,
+ ),
+ ),
+ ),
+ onReceiveClick = { },
+ ),
+ )
+ }
+}
\ No newline at end of file
diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTCollectionsEmpty.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTCollectionsEmpty.kt
new file mode 100644
index 0000000000..1376f56e72
--- /dev/null
+++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTCollectionsEmpty.kt
@@ -0,0 +1,74 @@
+package com.tangem.features.nft.collections.ui
+
+import android.content.res.Configuration
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.layout.*
+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.res.stringResource
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.tooling.preview.Preview
+import com.tangem.core.ui.components.PrimaryButton
+import com.tangem.core.ui.extensions.stringResourceSafe
+import com.tangem.core.ui.res.TangemTheme
+import com.tangem.core.ui.res.TangemThemePreview
+import com.tangem.features.nft.collections.entity.NFTCollectionsUM
+import com.tangem.features.nft.impl.R
+
+@Composable
+internal fun NFTCollectionsEmpty(state: NFTCollectionsUM.Empty, modifier: Modifier = Modifier) {
+ Box(
+ modifier = modifier
+ .fillMaxSize()
+ .padding(TangemTheme.dimens.spacing16),
+ ) {
+ Column(
+ modifier = Modifier
+ .padding(TangemTheme.dimens.spacing16)
+ .align(Alignment.Center),
+ horizontalAlignment = Alignment.CenterHorizontally,
+ ) {
+ Image(
+ painter = painterResource(R.drawable.ic_nft_placeholder_76),
+ contentDescription = null,
+ )
+ Text(
+ modifier = Modifier.padding(top = TangemTheme.dimens.spacing24),
+ text = stringResource(R.string.nft_collections_empty_title),
+ style = TangemTheme.typography.h3,
+ color = TangemTheme.colors.text.primary1,
+ textAlign = TextAlign.Center,
+ )
+ Text(
+ modifier = Modifier.padding(top = TangemTheme.dimens.spacing8),
+ text = stringResource(R.string.nft_collections_empty_description),
+ style = TangemTheme.typography.body1,
+ color = TangemTheme.colors.text.secondary,
+ textAlign = TextAlign.Center,
+ )
+ PrimaryButton(
+ modifier = Modifier
+ .padding(top = TangemTheme.dimens.spacing48)
+ .wrapContentWidth(),
+ text = stringResourceSafe(R.string.nft_collections_receive),
+ onClick = state.onReceiveClick,
+ )
+ }
+ }
+}
+
+@Preview(widthDp = 360, showBackground = true)
+@Preview(widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
+@Composable
+private fun Preview_NFTCollectionsEmpty() {
+ TangemThemePreview {
+ NFTCollectionsEmpty(
+ state = NFTCollectionsUM.Empty(
+ onReceiveClick = { },
+ ),
+ )
+ }
+}
\ No newline at end of file
diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTCollectionsFailed.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTCollectionsFailed.kt
new file mode 100644
index 0000000000..f16d193537
--- /dev/null
+++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTCollectionsFailed.kt
@@ -0,0 +1,54 @@
+package com.tangem.features.nft.collections.ui
+
+import android.content.res.Configuration
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.tooling.preview.Preview
+import com.tangem.core.ui.components.PrimaryButton
+import com.tangem.core.ui.components.UnableToLoadData
+import com.tangem.core.ui.extensions.stringResourceSafe
+import com.tangem.core.ui.res.TangemTheme
+import com.tangem.core.ui.res.TangemThemePreview
+import com.tangem.features.nft.collections.entity.NFTCollectionsUM
+import com.tangem.features.nft.impl.R
+
+@Composable
+internal fun NFTCollectionsFailed(state: NFTCollectionsUM.Failed, modifier: Modifier = Modifier) {
+ Box(
+ modifier = modifier
+ .fillMaxSize()
+ .padding(TangemTheme.dimens.spacing16),
+ ) {
+ UnableToLoadData(
+ modifier = Modifier
+ .align(Alignment.Center),
+ onRetryClick = state.onRetryClick,
+ )
+ PrimaryButton(
+ modifier = Modifier
+ .fillMaxWidth()
+ .align(Alignment.BottomCenter),
+ text = stringResourceSafe(R.string.nft_collections_receive),
+ onClick = { },
+ )
+ }
+}
+
+@Preview(widthDp = 360, showBackground = true)
+@Preview(widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
+@Composable
+private fun Preview_NFTCollectionsFailed() {
+ TangemThemePreview {
+ NFTCollectionsFailed(
+ state = NFTCollectionsUM.Failed(
+ onRetryClick = { },
+ onReceiveClick = { },
+ ),
+ )
+ }
+}
\ No newline at end of file
diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTSalePrice.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTSalePrice.kt
new file mode 100644
index 0000000000..ce4a1db2cf
--- /dev/null
+++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTSalePrice.kt
@@ -0,0 +1,40 @@
+package com.tangem.features.nft.collections.ui
+
+import androidx.compose.foundation.layout.width
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.text.style.TextOverflow
+import com.tangem.core.ui.components.TextShimmer
+import com.tangem.core.ui.res.TangemTheme
+import com.tangem.features.nft.collections.entity.NFTSalePriceUM
+
+@Composable
+internal fun NFTSalePrice(state: NFTSalePriceUM, modifier: Modifier = Modifier) {
+ when (state) {
+ is NFTSalePriceUM.Content -> {
+ Text(
+ modifier = modifier,
+ text = state.price,
+ style = TangemTheme.typography.caption2,
+ color = TangemTheme.colors.text.tertiary,
+ maxLines = 1,
+ overflow = TextOverflow.Ellipsis,
+ )
+ }
+ is NFTSalePriceUM.Failed -> {
+ Text(
+ modifier = modifier,
+ text = "",
+ style = TangemTheme.typography.caption2,
+ )
+ }
+ is NFTSalePriceUM.Loading -> {
+ TextShimmer(
+ modifier = modifier
+ .width(TangemTheme.dimens.size48),
+ style = TangemTheme.typography.caption2,
+ )
+ }
+ }
+}
\ No newline at end of file
diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/tokenlist/ui/OnrampTokenList.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/tokenlist/ui/OnrampTokenList.kt
index 679abe3866..c45da297d2 100644
--- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/tokenlist/ui/OnrampTokenList.kt
+++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/tokenlist/ui/OnrampTokenList.kt
@@ -6,11 +6,9 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
-import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.key
import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
@@ -18,6 +16,7 @@ import androidx.compose.ui.util.fastForEachIndexed
import com.tangem.common.ui.notifications.NotificationUM
import com.tangem.core.ui.components.SpacerH12
import com.tangem.core.ui.components.fields.SearchBar
+import com.tangem.core.ui.components.fields.TangemSearchBarDefaults
import com.tangem.core.ui.components.fields.entity.SearchBarUM
import com.tangem.core.ui.components.notifications.Notification
import com.tangem.core.ui.components.tokenlist.TokenListItem
@@ -74,16 +73,7 @@ internal fun TokenList(state: TokenListUM, modifier: Modifier = Modifier) {
private fun SearchBar(searchBarUM: SearchBarUM) {
SearchBar(
state = searchBarUM,
- colors = TextFieldDefaults.colors().copy(
- focusedContainerColor = TangemTheme.colors.field.focused,
- unfocusedContainerColor = TangemTheme.colors.field.focused,
- focusedTextColor = TangemTheme.colors.text.primary1,
- unfocusedTextColor = TangemTheme.colors.text.primary1,
- cursorColor = TangemTheme.colors.icon.primary1,
- focusedIndicatorColor = Color.Transparent,
- unfocusedIndicatorColor = Color.Transparent,
- disabledIndicatorColor = Color.Transparent,
- ),
+ colors = TangemSearchBarDefaults.secondaryTextFieldColors,
)
}
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/WalletNFTItem.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/WalletNFTItem.kt
index 850b0d78ab..7f2a8515b7 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/WalletNFTItem.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/WalletNFTItem.kt
@@ -394,7 +394,7 @@ private fun RowContentContainer(
@Preview(widthDp = 360)
@Preview(widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
-private fun Preview_WalletNFTItem_InLight(@PreviewParameter(WalletNFTItemProvider::class) state: WalletNFTItemUM) {
+private fun Preview_WalletNFTItem(@PreviewParameter(WalletNFTItemProvider::class) state: WalletNFTItemUM) {
TangemThemePreview {
WalletNFTItem(
state = state,