Skip to content

Commit

Permalink
feat: organization flow 카테고리 추가 #20
Browse files Browse the repository at this point in the history
  • Loading branch information
easyhz committed Jul 19, 2024
1 parent 4eb45ad commit 6716df4
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 13 deletions.
1 change: 1 addition & 0 deletions core/design-system/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,5 @@
<string name="organization_creation_title">그룹 만들기</string>
<string name="organization_creation_name_title">그룹 이름이 무엇인가요?</string>
<string name="organization_creation_name_placeholder">이름을 입력해 주세요.</string>
<string name="organization_creation_category_title">그룹의 카테고리를 모두 선택해 주세요</string>
</resources>
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package com.easyhz.noffice.feature.organization.component.creation

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.itemsIndexed
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.easyhz.noffice.core.design_system.R
import com.easyhz.noffice.core.design_system.component.button.CheckButton
import com.easyhz.noffice.core.design_system.component.button.CheckButtonDefaults
import com.easyhz.noffice.core.design_system.component.button.MediumButton
import com.easyhz.noffice.core.design_system.theme.Green100
import com.easyhz.noffice.core.design_system.theme.Green700
import com.easyhz.noffice.core.design_system.theme.Grey50
import com.easyhz.noffice.core.design_system.theme.Grey600
import com.easyhz.noffice.feature.organization.contract.creation.CreationIntent
import com.easyhz.noffice.feature.organization.screen.creation.OrganizationCreationViewModel

@Composable
internal fun CategoryView(
modifier: Modifier = Modifier,
viewModel: OrganizationCreationViewModel = hiltViewModel()
) {
val uiState by viewModel.uiState.collectAsStateWithLifecycle()

Column(
modifier = modifier
) {
CommonHeader(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 16.dp, horizontal = 8.dp),
title = stringResource(id = R.string.organization_creation_category_title)
)
LazyVerticalGrid(
modifier = Modifier.weight(1f).padding(top = 8.dp),
columns = GridCells.Fixed(2),
verticalArrangement = Arrangement.spacedBy(10.dp),
horizontalArrangement = Arrangement.spacedBy(7.dp)
) {
itemsIndexed(uiState.category) { index, item ->
CheckButton(
modifier = Modifier.weight(1f),
textAlign = TextAlign.Center,
text = item.title,
isComplete = item.isSelected,
color = CheckButtonDefaults(
completeContainerColor = Green100,
completeContentColor = Green700,
completeIconColor = null,
incompleteContainerColor = Grey50,
incompleteContentColor = Grey600,
incompleteIconColor = null
)
) {
viewModel.postIntent(CreationIntent.ClickCategoryItem(index))
}
}
}
MediumButton(
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 16.dp),
text = stringResource(id = R.string.sign_up_button),
enabled = uiState.enabledStepButton[uiState.step.currentStep] ?: false
) {
viewModel.postIntent(CreationIntent.ClickNextButton)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import com.easyhz.noffice.core.common.base.UiIntent
sealed class CreationIntent: UiIntent() {
data object ClickBackButton: CreationIntent()
data object ClickNextButton: CreationIntent()
data class ChangeGroupNameTextValue(val text: TextFieldValue): CreationIntent()
data class ChangeGroupNameTextValue(val text: String): CreationIntent()
data object ClearGroupName: CreationIntent()
data object ClearFocus: CreationIntent()
data class ClickCategoryItem(val selectedIndex: Int): CreationIntent()
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
package com.easyhz.noffice.feature.organization.contract.creation

import androidx.compose.ui.text.input.TextFieldValue
import com.easyhz.noffice.core.common.base.UiState
import com.easyhz.noffice.core.common.extension.toEnumMap
import com.easyhz.noffice.core.common.util.Step
import com.easyhz.noffice.core.common.util.toEnabledStepButton
import com.easyhz.noffice.feature.organization.util.creation.Category
import com.easyhz.noffice.feature.organization.util.creation.CreationStep
import com.easyhz.noffice.feature.organization.util.creation.toState
import java.util.EnumMap

data class CreationState(
val step: Step<CreationStep>,
val enabledStepButton: EnumMap<CreationStep, Boolean>,
val groupName: TextFieldValue
val groupName: String,
val category: List<CategoryState>
): UiState() {
companion object {
const val GROUP_NAME_MAX = 10
fun init() = CreationState(
step = Step(currentStep = CreationStep.GROUP_NAME, previousStep = null),
enabledStepButton = CreationStep.entries.toEnabledStepButton(),
groupName = TextFieldValue("")
groupName = "",
category = Category.toState()
)
}

Expand All @@ -28,4 +32,20 @@ data class CreationState(
),
)

}
fun CreationState.updateCategoryItem(selectedIndex: Int): CreationState {
val updatedCategory = category.mapIndexed { index, categoryState ->
categoryState.copy(isSelected = categoryState.isSelected.xor(index == selectedIndex))
}
return copy(
category = updatedCategory,
enabledStepButton = enabledStepButton.toMutableMap().apply {
this[step.currentStep] = updatedCategory.any { it.isSelected }
}.toEnumMap()
)
}
}

data class CategoryState(
val title: String,
val isSelected: Boolean
)
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.easyhz.noffice.feature.organization.screen.creation

import androidx.activity.compose.BackHandler
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.SizeTransform
import androidx.compose.animation.fadeIn
Expand All @@ -22,13 +23,14 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.easyhz.noffice.core.common.util.collectInSideEffectWithLifecycle
import com.easyhz.noffice.core.design_system.R
import com.easyhz.noffice.core.design_system.component.scaffold.NofficeBasicScaffold
import com.easyhz.noffice.core.design_system.component.scaffold.NofficeScaffold
import com.easyhz.noffice.core.design_system.component.topBar.DetailTopBar
import com.easyhz.noffice.core.design_system.extension.screenHorizonPadding
import com.easyhz.noffice.core.design_system.theme.Grey400
import com.easyhz.noffice.core.design_system.theme.White
import com.easyhz.noffice.core.design_system.util.topBar.DetailTopBarMenu
import com.easyhz.noffice.feature.organization.component.creation.CategoryView
import com.easyhz.noffice.feature.organization.component.creation.GroupNameView
import com.easyhz.noffice.feature.organization.contract.creation.CreationIntent
import com.easyhz.noffice.feature.organization.contract.creation.CreationSideEffect
import com.easyhz.noffice.feature.organization.util.creation.CreationStep

Expand All @@ -40,6 +42,10 @@ fun OrganizationCreationScreen(
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
val focusManager = LocalFocusManager.current

BackHandler(onBack = {
viewModel.postIntent(CreationIntent.ClickBackButton)
})

NofficeBasicScaffold(
modifier = modifier,
containerColor = White,
Expand All @@ -54,7 +60,7 @@ fun OrganizationCreationScreen(
tint = Grey400
)
},
onClick = { }
onClick = { viewModel.postIntent(CreationIntent.ClickBackButton) }
)
)
}
Expand All @@ -76,7 +82,7 @@ fun OrganizationCreationScreen(
) { targetScreen ->
when(targetScreen) {
CreationStep.GROUP_NAME -> { GroupNameView(modifier = Modifier.screenHorizonPadding()) }
CreationStep.CATEGORY -> { }
CreationStep.CATEGORY -> { CategoryView(modifier = Modifier.screenHorizonPadding()) }
CreationStep.IMAGE -> { }
CreationStep.END_DATE -> { }
CreationStep.PROMOTION -> { }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.easyhz.noffice.feature.organization.screen.creation

import androidx.compose.ui.text.input.TextFieldValue
import com.easyhz.noffice.core.common.base.BaseViewModel
import com.easyhz.noffice.core.common.util.updateStepButton
import com.easyhz.noffice.feature.organization.contract.creation.CreationIntent
Expand All @@ -23,6 +22,7 @@ class OrganizationCreationViewModel @Inject constructor(
is CreationIntent.ChangeGroupNameTextValue -> { onChangeGroupNameTextValue(intent.text) }
is CreationIntent.ClearGroupName -> { onClearGroupName() }
is CreationIntent.ClearFocus -> { onClearFocus() }
is CreationIntent.ClickCategoryItem -> { onClickCategoryItem(intent.selectedIndex) }
}
}

Expand All @@ -35,14 +35,15 @@ class OrganizationCreationViewModel @Inject constructor(
private fun onClickNextButton() {
currentState.step.currentStep.nextStep()?.let { nextStep ->
reduce { updateStep(currentStep = nextStep) }
postSideEffect { CreationSideEffect.ClearFocus }
} ?: run {
/* TODO NEXT */
}
}

private fun onChangeGroupNameTextValue(newText: TextFieldValue) {
if (newText.text.length > GROUP_NAME_MAX) return
val isEnabledButton = newText.text.isNotBlank()
private fun onChangeGroupNameTextValue(newText: String) {
if (newText.length > GROUP_NAME_MAX) return
val isEnabledButton = newText.isNotBlank()
reduce {
copy(
groupName = newText,
Expand All @@ -55,10 +56,14 @@ class OrganizationCreationViewModel @Inject constructor(
}

private fun onClearGroupName() {
reduce { copy(groupName = TextFieldValue("")) }
reduce { copy(groupName = "") }
}

private fun onClearFocus() {
postSideEffect { CreationSideEffect.ClearFocus }
}

private fun onClickCategoryItem(selectedIndex: Int) {
reduce { updateCategoryItem(selectedIndex) }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.easyhz.noffice.feature.organization.util.creation

import com.easyhz.noffice.feature.organization.contract.creation.CategoryState

//enum class Category {
//}

val Category = listOf("IT 계열", "문화 생활", "어학", "예술", "음악 · 공연", "스터디 · 연구", "스포츠", "창업", "종교", "마케팅 · 홍보", "자연과학", "기타")

fun List<String>.toState(): List<CategoryState> = map {
CategoryState(
it, false
)
}

0 comments on commit 6716df4

Please sign in to comment.