feat: improve UI with sentiment selection, input field, and feedback submission (#17)
Some checks are pending
Build / build (push) Waiting to run
Some checks are pending
Build / build (push) Waiting to run
This commit enhances the UI of the application with the following changes: - Adds sentiment selection via `FilterChip` components with leading icons and friendly names for each `Sentiment` option. - Introduces a `TextField` for user comments. - Implements feedback submission, which resets the selected sentiment and clears the comment field upon clicking the button. - Shows a snackbar to display feedback success after the button is clicked. - Improves `FilterChip` styling with `ChipDefaults` properties and uses larger font size. - Uses `Scaffold` to provide a structure for the app. Closes #4 Reviewed-on: #17 Co-authored-by: Ben Martin <ben.martin@sky.uk> Co-committed-by: Ben Martin <ben.martin@sky.uk>
This commit is contained in:
parent
3d2cc0a62c
commit
063ec7632f
1 changed files with 50 additions and 33 deletions
|
@ -8,24 +8,30 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material.Button
|
import androidx.compose.material.Button
|
||||||
|
import androidx.compose.material.ChipDefaults
|
||||||
import androidx.compose.material.ExperimentalMaterialApi
|
import androidx.compose.material.ExperimentalMaterialApi
|
||||||
import androidx.compose.material.FilterChip
|
import androidx.compose.material.FilterChip
|
||||||
import androidx.compose.material.Icon
|
import androidx.compose.material.Icon
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material.MaterialTheme
|
||||||
|
import androidx.compose.material.Scaffold
|
||||||
import androidx.compose.material.Text
|
import androidx.compose.material.Text
|
||||||
import androidx.compose.material.TextField
|
import androidx.compose.material.TextField
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.automirrored.filled.Send
|
import androidx.compose.material.icons.automirrored.filled.Send
|
||||||
|
import androidx.compose.material.rememberScaffoldState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.text.input.TextFieldValue
|
import androidx.compose.ui.text.input.TextFieldValue
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import org.jetbrains.compose.ui.tooling.preview.Preview
|
import org.jetbrains.compose.ui.tooling.preview.Preview
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterialApi::class)
|
@OptIn(ExperimentalMaterialApi::class)
|
||||||
|
@ -33,45 +39,56 @@ import org.jetbrains.compose.ui.tooling.preview.Preview
|
||||||
@Preview
|
@Preview
|
||||||
fun App() {
|
fun App() {
|
||||||
MaterialTheme {
|
MaterialTheme {
|
||||||
Box(
|
val scaffoldState = rememberScaffoldState()
|
||||||
modifier = Modifier.fillMaxHeight(),
|
val scope = rememberCoroutineScope()
|
||||||
contentAlignment = Alignment.Center,
|
|
||||||
) {
|
|
||||||
Column(
|
|
||||||
Modifier.fillMaxWidth(),
|
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
|
||||||
) {
|
|
||||||
Row(modifier = Modifier.padding(8.dp)) {
|
|
||||||
val state = remember { mutableStateOf(Sentiment.HAPPY) }
|
|
||||||
for (emotion in Sentiment.entries) {
|
|
||||||
FilterChip(
|
|
||||||
onClick = { state.value = emotion },
|
|
||||||
selected = state.value == emotion,
|
|
||||||
modifier = Modifier.padding(8.dp),
|
|
||||||
leadingIcon = { Text(emotion.leadingIcon) },
|
|
||||||
) {
|
|
||||||
Text(emotion.friendlyName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row(modifier = Modifier.padding(8.dp)) {
|
Scaffold(scaffoldState = scaffoldState) {
|
||||||
var text by rememberSaveable(stateSaver = TextFieldValue.Saver) {
|
Box(
|
||||||
|
modifier = Modifier.fillMaxHeight(),
|
||||||
|
contentAlignment = Alignment.Center,
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
Modifier.fillMaxWidth(),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
) {
|
||||||
|
val sentiment = remember { mutableStateOf(Sentiment.HAPPY) }
|
||||||
|
var comment by rememberSaveable(stateSaver = TextFieldValue.Saver) {
|
||||||
mutableStateOf(
|
mutableStateOf(
|
||||||
TextFieldValue("")
|
TextFieldValue("")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
TextField(
|
Row(modifier = Modifier.padding(8.dp)) {
|
||||||
value = text,
|
for (emotion in Sentiment.entries) {
|
||||||
onValueChange = { text = it },
|
FilterChip(
|
||||||
label = { Text("Your comment") },
|
onClick = { sentiment.value = emotion },
|
||||||
modifier = Modifier.height(100.dp).fillMaxWidth().padding(8.dp),
|
selected = sentiment.value == emotion,
|
||||||
)
|
modifier = Modifier.padding(8.dp),
|
||||||
}
|
leadingIcon = { Text(emotion.leadingIcon, fontSize = 20.sp) },
|
||||||
|
colors = ChipDefaults.outlinedFilterChipColors(),
|
||||||
|
border = ChipDefaults.outlinedBorder,
|
||||||
|
) {
|
||||||
|
Text(emotion.friendlyName, fontSize = 20.sp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Row(modifier = Modifier.padding(8.dp)) {
|
Row(modifier = Modifier.padding(8.dp)) {
|
||||||
Button(onClick = { /* Handle submit */ }, modifier = Modifier.padding(8.dp)) {
|
TextField(
|
||||||
Icon(Icons.AutoMirrored.Filled.Send, contentDescription = "Send")
|
value = comment,
|
||||||
|
onValueChange = { comment = it },
|
||||||
|
label = { Text("Your comment") },
|
||||||
|
modifier = Modifier.height(100.dp).fillMaxWidth().padding(8.dp),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Row(modifier = Modifier.padding(8.dp)) {
|
||||||
|
Button(onClick = {
|
||||||
|
sentiment.value = Sentiment.HAPPY
|
||||||
|
comment = TextFieldValue("")
|
||||||
|
scope.launch { scaffoldState.snackbarHostState.showSnackbar("Feedback sent") }
|
||||||
|
}, modifier = Modifier.padding(8.dp)) {
|
||||||
|
Icon(Icons.AutoMirrored.Filled.Send, contentDescription = "Send")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue