From 0d4556398f7a02f449209ac72f1deb4c7f56ac9f Mon Sep 17 00:00:00 2001 From: Doyoon Kim Date: Sat, 30 Nov 2024 22:38:42 +0900 Subject: [PATCH] [REFACT] User Report Submission Feature - Add pop-up style notification to inform a submission status to users. - UI components must be finite later. --- .../doyoonkim/knutice/model/DataWrappers.kt | 3 +- .../knutice/presentation/CustomerService.kt | 169 +++++++++++------- .../viewModel/CustomerServiceViewModel.kt | 37 +++- 3 files changed, 140 insertions(+), 69 deletions(-) diff --git a/app/src/main/java/com/doyoonkim/knutice/model/DataWrappers.kt b/app/src/main/java/com/doyoonkim/knutice/model/DataWrappers.kt index 5d3e6fe..ace3ac8 100644 --- a/app/src/main/java/com/doyoonkim/knutice/model/DataWrappers.kt +++ b/app/src/main/java/com/doyoonkim/knutice/model/DataWrappers.kt @@ -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 ) diff --git a/app/src/main/java/com/doyoonkim/knutice/presentation/CustomerService.kt b/app/src/main/java/com/doyoonkim/knutice/presentation/CustomerService.kt index d5bd2f4..a3e00d4 100644 --- a/app/src/main/java/com/doyoonkim/knutice/presentation/CustomerService.kt +++ b/app/src/main/java/com/doyoonkim/knutice/presentation/CustomerService.kt @@ -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 @@ -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 @@ -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 @@ -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" + ) + } + } + + } } + } } diff --git a/app/src/main/java/com/doyoonkim/knutice/viewModel/CustomerServiceViewModel.kt b/app/src/main/java/com/doyoonkim/knutice/viewModel/CustomerServiceViewModel.kt index 6fbc2df..dc44276 100644 --- a/app/src/main/java/com/doyoonkim/knutice/viewModel/CustomerServiceViewModel.kt +++ b/app/src/main/java/com/doyoonkim/knutice/viewModel/CustomerServiceViewModel.kt @@ -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, @@ -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 ) } }