ProductDetailsScreen
OK
This commit is contained in:
parent
2bb00741f4
commit
4a2db6e30b
@ -0,0 +1,11 @@
|
|||||||
|
package com.juceliodev.fooddeliverymyapplication.data
|
||||||
|
|
||||||
|
data class OrderState(
|
||||||
|
val amount: Int,
|
||||||
|
val totalPrice: String
|
||||||
|
)
|
||||||
|
|
||||||
|
val OrderData = OrderState(
|
||||||
|
amount = 5,
|
||||||
|
totalPrice = "$27.45"
|
||||||
|
)
|
@ -0,0 +1,44 @@
|
|||||||
|
package com.juceliodev.fooddeliverymyapplication.data
|
||||||
|
|
||||||
|
data class ProductNutritionState(
|
||||||
|
val calories: Calories,
|
||||||
|
val nutrition: List<NutritionState>
|
||||||
|
)
|
||||||
|
|
||||||
|
data class Calories(
|
||||||
|
val value: String,
|
||||||
|
val unit: String
|
||||||
|
)
|
||||||
|
|
||||||
|
data class NutritionState(
|
||||||
|
val amount: String,
|
||||||
|
val unit: String,
|
||||||
|
val title: String
|
||||||
|
)
|
||||||
|
|
||||||
|
val ProductNutritionData = ProductNutritionState(
|
||||||
|
calories = Calories(
|
||||||
|
value = "650",
|
||||||
|
unit = "Cal"
|
||||||
|
),
|
||||||
|
nutrition = listOf(
|
||||||
|
NutritionState(
|
||||||
|
amount = "35",
|
||||||
|
unit = "g",
|
||||||
|
title = "Total Fat (45% DV)"
|
||||||
|
),
|
||||||
|
NutritionState(
|
||||||
|
amount = "43",
|
||||||
|
unit = "g",
|
||||||
|
title = "Total Carbs (16% DV)"
|
||||||
|
),
|
||||||
|
NutritionState(
|
||||||
|
amount = "36",
|
||||||
|
unit = "g",
|
||||||
|
title = "Protein"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
|||||||
|
package com.juceliodev.fooddeliverymyapplication.data
|
||||||
|
|
||||||
|
import androidx.annotation.DrawableRes
|
||||||
|
import com.juceliodev.fooddeliverymyapplication.R
|
||||||
|
|
||||||
|
data class ProductHighlightState(
|
||||||
|
val text: String,
|
||||||
|
val type: ProductHighlightType
|
||||||
|
)
|
||||||
|
|
||||||
|
enum class ProductHighlightType {
|
||||||
|
PRIMARY, SECONDARY
|
||||||
|
}
|
||||||
|
|
||||||
|
data class ProductPreviewState(
|
||||||
|
val headline: String = "Mr. Cheezy",
|
||||||
|
@DrawableRes val productImg: Int = R.drawable.img_burger,
|
||||||
|
val highlights: List<ProductHighlightState> = listOf(
|
||||||
|
ProductHighlightState(
|
||||||
|
text = "Classic Taste",
|
||||||
|
type = ProductHighlightType.SECONDARY
|
||||||
|
),
|
||||||
|
ProductHighlightState(
|
||||||
|
text = "Bestseller",
|
||||||
|
type = ProductHighlightType.PRIMARY
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
@ -0,0 +1,92 @@
|
|||||||
|
package com.juceliodev.fooddeliverymyapplication.ui.screen.components
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material3.Surface
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.juceliodev.fooddeliverymyapplication.data.ProductHighlightState
|
||||||
|
import com.juceliodev.fooddeliverymyapplication.data.ProductHighlightType
|
||||||
|
import com.juceliodev.fooddeliverymyapplication.ui.theme.AppTheme
|
||||||
|
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ProductHighlights(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
highlights: List<ProductHighlightState>
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
modifier = modifier,
|
||||||
|
horizontalAlignment = Alignment.Start,
|
||||||
|
verticalArrangement = Arrangement.spacedBy(4.dp)
|
||||||
|
) {
|
||||||
|
highlights.onEach { item ->
|
||||||
|
Highlight(
|
||||||
|
text = item.text,
|
||||||
|
colors = HighlightDefaults.colors(item.type)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun Highlight(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
text: String,
|
||||||
|
colors: HighlightColors = HighlightDefaults.defaultColors
|
||||||
|
) {
|
||||||
|
Surface(
|
||||||
|
modifier = modifier,
|
||||||
|
shape = RoundedCornerShape(percent = 50),
|
||||||
|
color = colors.containerColor,
|
||||||
|
contentColor = colors.contentColor
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.padding(
|
||||||
|
vertical = 10.dp,
|
||||||
|
horizontal = 12.dp
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = text,
|
||||||
|
style = AppTheme.typography.titleSmall.copy(fontWeight = FontWeight.Bold)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private object HighlightDefaults {
|
||||||
|
|
||||||
|
val defaultColors = HighlightColors(
|
||||||
|
containerColor = Color.Unspecified,
|
||||||
|
contentColor = Color.Unspecified
|
||||||
|
)
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun colors(type: ProductHighlightType): HighlightColors = when (type) {
|
||||||
|
ProductHighlightType.SECONDARY -> HighlightColors(
|
||||||
|
containerColor = AppTheme.colors.actionSurface,
|
||||||
|
contentColor = AppTheme.colors.onActionSurface
|
||||||
|
)
|
||||||
|
|
||||||
|
ProductHighlightType.PRIMARY -> HighlightColors(
|
||||||
|
containerColor = AppTheme.colors.highlightSurface,
|
||||||
|
contentColor = AppTheme.colors.onHighlightSurface
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
private data class HighlightColors(
|
||||||
|
val containerColor: Color,
|
||||||
|
val contentColor: Color
|
||||||
|
)
|
@ -0,0 +1,108 @@
|
|||||||
|
package com.juceliodev.fooddeliverymyapplication.ui.screen.components
|
||||||
|
|
||||||
|
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.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.juceliodev.fooddeliverymyapplication.data.Calories
|
||||||
|
import com.juceliodev.fooddeliverymyapplication.data.NutritionState
|
||||||
|
import com.juceliodev.fooddeliverymyapplication.data.ProductNutritionState
|
||||||
|
import com.juceliodev.fooddeliverymyapplication.ui.theme.AppTheme
|
||||||
|
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ProductNutritionSection(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
state: ProductNutritionState
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
modifier = modifier.fillMaxWidth(),
|
||||||
|
verticalArrangement = Arrangement.spacedBy(16.dp)
|
||||||
|
) {
|
||||||
|
SectionHeader(
|
||||||
|
title = "Nutrition facts",
|
||||||
|
calories = state.calories
|
||||||
|
)
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
state.nutrition.onEach { item -> NutritionItem(state = item) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun SectionHeader(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
title: String,
|
||||||
|
calories: Calories
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
modifier = modifier.fillMaxWidth(),
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = title,
|
||||||
|
style = AppTheme.typography.titleLarge,
|
||||||
|
color = AppTheme.colors.onBackground
|
||||||
|
)
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(4.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = calories.value,
|
||||||
|
style = AppTheme.typography.titleMedium,
|
||||||
|
color = AppTheme.colors.onBackground
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = calories.unit,
|
||||||
|
style = AppTheme.typography.titleMedium,
|
||||||
|
color = AppTheme.colors.onBackground
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun NutritionItem(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
state: NutritionState
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
modifier = modifier,
|
||||||
|
verticalArrangement = Arrangement.spacedBy(2.dp),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = state.amount,
|
||||||
|
style = AppTheme.typography.titleMedium,
|
||||||
|
fontWeight = FontWeight.Light,
|
||||||
|
color = AppTheme.colors.onBackground
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = state.unit,
|
||||||
|
style = AppTheme.typography.titleMedium,
|
||||||
|
color = AppTheme.colors.onBackground,
|
||||||
|
fontWeight = FontWeight.Light
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Text(
|
||||||
|
text = state.title,
|
||||||
|
style = AppTheme.typography.label,
|
||||||
|
color = AppTheme.colors.onBackground
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,145 @@
|
|||||||
|
package com.juceliodev.fooddeliverymyapplication.ui.screen.components
|
||||||
|
|
||||||
|
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.IntrinsicSize
|
||||||
|
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.statusBarsPadding
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.Surface
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.layout.ContentScale
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.constraintlayout.compose.ConstraintLayout
|
||||||
|
import com.juceliodev.fooddeliverymyapplication.R
|
||||||
|
import com.juceliodev.fooddeliverymyapplication.data.ProductPreviewState
|
||||||
|
import com.juceliodev.fooddeliverymyapplication.ui.theme.AppTheme
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ProductPreviewSection(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
state: ProductPreviewState
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = modifier.height(IntrinsicSize.Max)
|
||||||
|
) {
|
||||||
|
ProductBackground(
|
||||||
|
Modifier.padding(bottom = 24.dp)
|
||||||
|
)
|
||||||
|
Content(
|
||||||
|
state = state,
|
||||||
|
modifier = Modifier
|
||||||
|
.statusBarsPadding()
|
||||||
|
.padding(top = 24.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun ProductBackground(
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.background(
|
||||||
|
color = AppTheme.colors.secondarySurface,
|
||||||
|
shape = RoundedCornerShape(bottomStart = 32.dp, bottomEnd = 32.dp)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun Content(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
state: ProductPreviewState
|
||||||
|
) {
|
||||||
|
ConstraintLayout(
|
||||||
|
modifier = modifier.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
val (actionBar, highlights, productImg) = createRefs()
|
||||||
|
|
||||||
|
ActionBar(
|
||||||
|
headline = state.headline,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(horizontal = 19.dp)
|
||||||
|
.constrainAs(actionBar) {
|
||||||
|
top.linkTo(parent.top)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
Image(
|
||||||
|
painter = painterResource(id = state.productImg),
|
||||||
|
contentDescription = null,
|
||||||
|
contentScale = ContentScale.FillHeight,
|
||||||
|
modifier = Modifier
|
||||||
|
.height(256.dp)
|
||||||
|
.constrainAs(productImg) {
|
||||||
|
end.linkTo(parent.end)
|
||||||
|
top.linkTo(anchor = actionBar.bottom, margin = 20.dp)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
ProductHighlights(
|
||||||
|
highlights = state.highlights,
|
||||||
|
modifier = Modifier.constrainAs(highlights) {
|
||||||
|
start.linkTo(anchor = parent.start, margin = 19.dp)
|
||||||
|
top.linkTo(productImg.top)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun ActionBar(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
headline: String
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
modifier = modifier.fillMaxWidth(),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = headline,
|
||||||
|
style = AppTheme.typography.headline,
|
||||||
|
color = AppTheme.colors.onSecondarySurface
|
||||||
|
)
|
||||||
|
CloseButton()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun CloseButton(
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
Surface(
|
||||||
|
modifier = modifier.size(44.dp),
|
||||||
|
shape = RoundedCornerShape(16.dp),
|
||||||
|
color = AppTheme.colors.actionSurface,
|
||||||
|
contentColor = AppTheme.colors.secondarySurface
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = modifier.fillMaxSize(),
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(id = R.drawable.ic_close),
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier.size(24.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user