Skip to content

Commit

Permalink
Added read only alert form
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathanarodr committed May 3, 2024
1 parent 83f85fd commit 7728810
Show file tree
Hide file tree
Showing 6 changed files with 309 additions and 15 deletions.
2 changes: 1 addition & 1 deletion app/src/main/kotlin/br/com/stonks/ui/BottomAppBarLayout.kt
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ internal fun BottomAppBarLayout(
navController.navigate(MainNavDestination.HOME.route)
}
NavigationItem(
icon = R.drawable.ic_alert,
icon = R.drawable.ic_radar,
label = br.com.stonks.R.string.main_nav_action_stock_alert,
selected = false,
) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
package br.com.stonks.feature.stocks.ui.states

import br.com.stonks.common.states.UiEvent
import br.com.stonks.feature.stocks.ui.model.AlertUiModel

internal sealed class StockUiEvent : UiEvent {

data object RegisterAlert : StockUiEvent()
data class RegisterAlert(
val data: AlertUiModel,
) : StockUiEvent()

data class RemoveAlert(
val id: Long,
) : StockUiEvent()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,272 @@
package br.com.stonks.feature.stocks.ui.view

import androidx.compose.foundation.Image
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.Spacer
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.wrapContentHeight
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.OutlinedCard
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
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.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import br.com.stonks.common.formatters.formatCurrency
import br.com.stonks.designsystem.components.TagLayout
import br.com.stonks.designsystem.tokens.ColorToken
import br.com.stonks.designsystem.tokens.SpacingToken
import br.com.stonks.feature.stocks.R
import br.com.stonks.feature.stocks.domain.types.StockAlertType
import br.com.stonks.feature.stocks.domain.types.StockStatusType
import br.com.stonks.feature.stocks.ui.model.AlertUiModel
import br.com.stonks.feature.stocks.utils.getDescription
import kotlinx.coroutines.launch

@Composable
private fun AlertForms(
uiModel: AlertUiModel,
modifier: Modifier = Modifier,
) {
Column(
modifier = modifier.fillMaxWidth()
.padding(SpacingToken.xl)
) {
OutlinedTextField(
value = uiModel.ticket,
onValueChange = { },
enabled = false,
label = { Text("Ticket") },
modifier = Modifier.fillMaxWidth(),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
)

Spacer(modifier = Modifier.height(SpacingToken.lg))

OutlinedTextField(
value = uiModel.alertValue.formatCurrency(),
onValueChange = { },
enabled = false,
label = { Text("Alertar em") },
modifier = Modifier.fillMaxWidth(),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Decimal)
)
}
}

@Composable
@OptIn(ExperimentalMaterial3Api::class)
private fun AlertActions(
uiModel: AlertUiModel,
onEditItem: (data: AlertUiModel) -> Unit,
onDeleteItem: (id: Long) -> Unit,
) {
val sheetState = rememberModalBottomSheetState()
val scope = rememberCoroutineScope()
var showBottomSheet by remember { mutableStateOf(false) }

IconButton(
onClick = { onDeleteItem(uiModel.id) },
) {
Icon(
painter = painterResource(
id = br.com.stonks.designsystem.R.drawable.ic_trash
),
contentDescription = stringResource(id = R.string.alert_action_delete),
)
}
IconButton(
onClick = { showBottomSheet = true },
) {
Icon(
painter = painterResource(
id = br.com.stonks.designsystem.R.drawable.ic_edit
),
contentDescription = stringResource(id = R.string.alert_action_edit),
)
}

if (showBottomSheet) {
ModalBottomSheet(
modifier = Modifier,
sheetState = sheetState,
onDismissRequest = { showBottomSheet = false },
) {
AlertForms(
uiModel = uiModel,
)
Row(
modifier = Modifier
.fillMaxWidth()
.padding(SpacingToken.xl),
horizontalArrangement = Arrangement.End,
) {
OutlinedButton(onClick = {
scope.launch { sheetState.hide() }.invokeOnCompletion {
if (!sheetState.isVisible) {
onEditItem(uiModel)
showBottomSheet = false
}
}
}) {
Text(stringResource(id = R.string.alert_action_close))
}
}
}
}
}

@Composable
private fun AlertLayoutTitle(
uiModel: AlertUiModel,
modifier: Modifier = Modifier,
onEditItem: (data: AlertUiModel) -> Unit,
onDeleteItem: (id: Long) -> Unit,
) {
Row(
modifier = modifier
.fillMaxWidth()
.wrapContentHeight(),
verticalAlignment = Alignment.CenterVertically,
) {
Row(
modifier = Modifier.weight(1f),
) {
Text(
text = uiModel.ticket,
style = MaterialTheme.typography.titleSmall.copy(
fontWeight = FontWeight.ExtraBold,
),
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
TagLayout(
modifier = Modifier.padding(start = SpacingToken.md),
containerColor = uiModel.tagColor,
contentColor = ColorToken.NeutralWhite,
label = stringResource(id = uiModel.status.getDescription()),
)
}
AlertActions(
uiModel = uiModel,
onEditItem = { onEditItem(uiModel) },
onDeleteItem = { onDeleteItem(uiModel.id) },
)
}
}

@Composable
private fun AlertLayoutContent(
alertValue: Double,
modifier: Modifier = Modifier,
) {
Row(
modifier = modifier
.fillMaxWidth()
.wrapContentHeight()
) {
Image(
painter = painterResource(id = br.com.stonks.designsystem.R.drawable.ic_broken_image),
contentDescription = null,
modifier = Modifier.size(40.dp),
contentScale = ContentScale.FillWidth
)
Column(
modifier = Modifier.padding(start = SpacingToken.lg),
) {
Text(
text = stringResource(id = R.string.alert_price),
style = MaterialTheme.typography.titleSmall,
color = ColorToken.Grayscale300,
)
Spacer(modifier = Modifier.height(SpacingToken.xs))
Text(
text = alertValue.formatCurrency(),
style = MaterialTheme.typography.titleSmall.copy(
fontWeight = FontWeight.ExtraBold,
),
)
}
}
}

@Composable
internal fun AlertCard(
uiModel: AlertUiModel,
modifier: Modifier = Modifier,
onEditItem: (data: AlertUiModel) -> Unit,
onDeleteItem: (id: Long) -> Unit,
) {
OutlinedCard(
modifier = modifier
.fillMaxWidth()
.wrapContentHeight(),
) {
Column(
modifier = Modifier
.background(ColorToken.NeutralWhite)
.padding(SpacingToken.xl)
) {
AlertLayoutTitle(
uiModel = uiModel,
onEditItem = { onEditItem(uiModel) },
onDeleteItem = { onDeleteItem(uiModel.id) },
)
HorizontalDivider(
modifier = Modifier.padding(vertical = SpacingToken.lg),
color = ColorToken.Grayscale100,
)
AlertLayoutContent(
alertValue = uiModel.alertValue,
)
}
}
}

@Preview(showBackground = true)
@Composable
private fun AlertLayoutPreview() {
Column(
modifier = Modifier.padding(SpacingToken.xl)
) {
AlertCard(
uiModel = AlertUiModel(
id = 1L,
ticket = "GOGL34",
alertValue = 71.0,
status = StockStatusType.AVAILABLE,
alert = StockAlertType.HIGH_PRICE,
tagColor = ColorToken.HighlightGreen,
),
onEditItem = { },
onDeleteItem = { },
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
Expand All @@ -25,8 +21,10 @@ import br.com.stonks.feature.stocks.domain.types.StockAlertType
import br.com.stonks.feature.stocks.domain.types.StockStatusType
import br.com.stonks.feature.stocks.ui.model.AlertUiModel
import br.com.stonks.feature.stocks.ui.model.StockAlertUiModel
import br.com.stonks.feature.stocks.ui.states.StockUiEvent
import br.com.stonks.feature.stocks.ui.states.StockUiState
import br.com.stonks.feature.stocks.ui.viewmodel.STOCK_VM_QUALIFIER
import br.com.stonks.feature.stocks.ui.viewmodel.StockViewModel
import org.koin.androidx.compose.koinViewModel
import org.koin.core.qualifier.named
import timber.log.Timber
Expand All @@ -35,8 +33,8 @@ import timber.log.Timber
private fun StockAlertContent(
uiModel: StockAlertUiModel,
modifier: Modifier = Modifier,
onEditItem: () -> Unit,
onDeleteItem: () -> Unit,
onEditItem: (data: AlertUiModel) -> Unit,
onDeleteItem: (id: Long) -> Unit,
) {
LazyColumn(
modifier = modifier,
Expand All @@ -54,8 +52,8 @@ private fun StockAlertContent(
items(uiModel.stockAlerts) { alert ->
AlertCard(
uiModel = alert,
onEditItem = { onEditItem() },
onDeleteItem = { onDeleteItem() },
onEditItem = { onEditItem(alert) },
onDeleteItem = { onDeleteItem(alert.id) },
)
}
}
Expand All @@ -70,7 +68,6 @@ fun StockAlertScreen(
),
) {
val uiState = viewModel.uiState.collectAsStateWithLifecycle()
var selected by remember { mutableStateOf(false) }

when (uiState.value) {
is StockUiState.Loading -> {
Expand All @@ -81,8 +78,16 @@ fun StockAlertScreen(
StockAlertContent(
uiModel = (uiState.value as StockUiState.Success).data,
modifier = modifier,
onEditItem = { },
onDeleteItem = { },
onEditItem = { data ->
(viewModel as StockViewModel).dispatchUiEvent(
StockUiEvent.RegisterAlert(data)
)
},
onDeleteItem = { id ->
(viewModel as StockViewModel).dispatchUiEvent(
StockUiEvent.RemoveAlert(id)
)
},
)
}

Expand Down
Loading

0 comments on commit 7728810

Please sign in to comment.