Skip to content

Commit

Permalink
[REFACT] User Report Submission Feature
Browse files Browse the repository at this point in the history
  - Add pop-up style notification to inform a submission status to users.
  - UI components must be finite later.
  • Loading branch information
doyoonkim3312 committed Nov 30, 2024
1 parent c3d1a9a commit 0d45563
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ data class DetailedContentState(
data class CustomerServiceReportState(
val userReport: String = "",
val reachedMaxCharacters: Boolean = false,
val isSubmissionFailed: Boolean = false
val isSubmissionFailed: Boolean = false,
val isSubmissionCompleted: Boolean = false
)

169 changes: 109 additions & 60 deletions app/src/main/java/com/doyoonkim/knutice/presentation/CustomerService.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package com.doyoonkim.knutice.presentation

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.scaleIn
import androidx.compose.animation.scaleOut
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
Expand All @@ -11,9 +15,11 @@ import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldDefaults
Expand All @@ -22,6 +28,7 @@ import androidx.compose.runtime.collectAsState
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.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
Expand All @@ -44,76 +51,118 @@ fun CustomerService(
onCloseRequested: () -> Unit = {}
) {
val uiState by viewModel.uiState.collectAsState()

Column(
Box(
modifier = modifier.fillMaxSize()
.windowInsetsPadding(WindowInsets.systemBars),
verticalArrangement = Arrangement.Top,
horizontalAlignment = Alignment.CenterHorizontally
.windowInsetsPadding(WindowInsets.systemBars)
) {
Text(
text = stringResource(R.string.customer_service_subtitile_1),
fontWeight = FontWeight.SemiBold,
color = MaterialTheme.colorScheme.textPurple,
fontSize = 14.sp,
modifier = Modifier.fillMaxWidth()
)
Text(
text = stringResource(R.string.customer_service_subtitle_2),
fontWeight = FontWeight.SemiBold,
color = MaterialTheme.colorScheme.textPurple,
fontSize = 14.sp,
modifier = Modifier.fillMaxWidth()
)


Box(
modifier = Modifier.fillMaxWidth().weight(5f)
.padding(top = 25.dp, bottom = 25.dp)
Column(
modifier = Modifier.clickable(!uiState.isSubmissionCompleted) { },
verticalArrangement = Arrangement.Top,
horizontalAlignment = Alignment.CenterHorizontally
) {
TextField(
modifier = Modifier.fillMaxSize(),
value = uiState.userReport,
placeholder = { Text(stringResource(R.string.placeholder_customer_report)) },
onValueChange = {
viewModel.updateUserReportContent(it)
},
colors = TextFieldDefaults.colors(
focusedTextColor = MaterialTheme.colorScheme.title,
unfocusedTextColor = MaterialTheme.colorScheme.subTitle,
focusedContainerColor = MaterialTheme.colorScheme.containerBackground,
unfocusedContainerColor = MaterialTheme.colorScheme.containerBackground,
focusedIndicatorColor = Color.Transparent,
unfocusedIndicatorColor = Color.Transparent,
disabledIndicatorColor = Color.Transparent
),
shape = RoundedCornerShape(15.dp)
Text(
text = stringResource(R.string.customer_service_subtitile_1),
fontWeight = FontWeight.SemiBold,
color = MaterialTheme.colorScheme.textPurple,
fontSize = 14.sp,
modifier = Modifier.fillMaxWidth()
)

Text(
text = "${uiState.userReport.length}/500",
fontSize = 12.sp,
fontWeight = FontWeight.Medium,
color = MaterialTheme.colorScheme.subTitle,
modifier = Modifier.wrapContentSize()
.padding(15.dp)
.align(Alignment.BottomEnd)
text = stringResource(R.string.customer_service_subtitle_2),
fontWeight = FontWeight.SemiBold,
color = MaterialTheme.colorScheme.textPurple,
fontSize = 14.sp,
modifier = Modifier.fillMaxWidth()
)


Box(
modifier = Modifier.fillMaxWidth().weight(5f)
.padding(top = 25.dp, bottom = 25.dp)
) {
TextField(
modifier = Modifier.fillMaxSize(),
value = uiState.userReport,
placeholder = { Text(stringResource(R.string.placeholder_customer_report)) },
onValueChange = {
viewModel.updateUserReportContent(it)
},
colors = TextFieldDefaults.colors(
focusedTextColor = MaterialTheme.colorScheme.title,
unfocusedTextColor = MaterialTheme.colorScheme.subTitle,
focusedContainerColor = MaterialTheme.colorScheme.containerBackground,
unfocusedContainerColor = MaterialTheme.colorScheme.containerBackground,
focusedIndicatorColor = Color.Transparent,
unfocusedIndicatorColor = Color.Transparent,
disabledIndicatorColor = Color.Transparent
),
shape = RoundedCornerShape(15.dp)
)

Text(
text = "${uiState.userReport.length}/500",
fontSize = 12.sp,
fontWeight = FontWeight.Medium,
color = MaterialTheme.colorScheme.subTitle,
modifier = Modifier.wrapContentSize()
.padding(15.dp)
.align(Alignment.BottomEnd)
)
}

Button(
modifier = Modifier.fillMaxWidth().wrapContentHeight(),
enabled = true,
shape = RoundedCornerShape(10.dp),
onClick = { viewModel.submitUserReport() }
) {
Text(
text = stringResource(R.string.btn_submit),
fontSize = 16.sp,
fontWeight = FontWeight.Bold,
modifier = Modifier.padding(10.dp)
)
}
}

Button(
modifier = Modifier.fillMaxWidth().wrapContentHeight(),
enabled = true,
shape = RoundedCornerShape(10.dp),
onClick = { viewModel.submitUserReport() }
AnimatedVisibility(
modifier = Modifier.wrapContentSize().align(Alignment.Center),
visible = uiState.isSubmissionCompleted,
enter = scaleIn(),
exit = scaleOut()
) {
Text(
text = stringResource(R.string.btn_submit),
fontSize = 16.sp,
fontWeight = FontWeight.Bold,
modifier = Modifier.padding(10.dp)
)
Surface(
modifier = Modifier.padding(15.dp)
.clip(RoundedCornerShape(15.dp)),
color = MaterialTheme.colorScheme.subTitle
) {
Column(
modifier = Modifier.wrapContentHeight()
) {
Text(
fontSize = 20.sp,
fontWeight = FontWeight.Bold,
text = "Submission Completed"
)
Text(
fontSize = 14.sp,
fontWeight = FontWeight.Bold,
text = "Submission Completed"
)
Button(
onClick = { viewModel.updateCompletionState() }
) {
Text(
fontSize = 14.sp,
fontWeight = FontWeight.Bold,
text = "Confirm"
)
}
}

}
}

}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,15 @@ class CustomerServiceViewModel @Inject constructor(
}
}

fun updateCompletionState() {
_uiState.update {
it.copy(
isSubmissionCompleted = false,
isSubmissionFailed = false
)
}
}

fun submitUserReport() {
val report = ReportRequest(
content = _uiState.value.userReport,
Expand All @@ -53,21 +62,33 @@ class CustomerServiceViewModel @Inject constructor(

viewModelScope.launch {
withContext(Dispatchers.IO) {
val submission = async { remoteSource.submitUserReport(report) }
val submission = async { remoteSource.submitUserReport(report, true) }

submission.await().fold(
onSuccess = {
_uiState.update {
it.copy(
userReport = "",
reachedMaxCharacters = false
)
onSuccess = { submissionResult ->
if (submissionResult) {
_uiState.update {
it.copy(
userReport = "",
reachedMaxCharacters = false,
isSubmissionFailed = false,
isSubmissionCompleted = true
)
}
} else {
_uiState.update {
it.copy(
isSubmissionFailed = true,
isSubmissionCompleted = true
)
}
}
},
onFailure = {
_uiState.update {
it.copy(
isSubmissionFailed = true
isSubmissionFailed = true,
isSubmissionCompleted = true
)
}
}
Expand Down

0 comments on commit 0d45563

Please sign in to comment.