diff --git a/core/src/main/java/com/terning/core/designsystem/component/bottomsheet/ProfileBottomSheet.kt b/core/src/main/java/com/terning/core/designsystem/component/bottomsheet/ProfileBottomSheet.kt index 9382ceb7a..9109deb87 100644 --- a/core/src/main/java/com/terning/core/designsystem/component/bottomsheet/ProfileBottomSheet.kt +++ b/core/src/main/java/com/terning/core/designsystem/component/bottomsheet/ProfileBottomSheet.kt @@ -30,6 +30,7 @@ import com.terning.core.R import com.terning.core.designsystem.theme.TerningMain import com.terning.core.designsystem.theme.TerningTheme import com.terning.core.extension.noRippleClickable +import com.terning.core.type.ProfileImage import kotlinx.coroutines.launch /** @@ -38,15 +39,15 @@ import kotlinx.coroutines.launch * @param modifier 바텀시트에 적용할 Modifier입니다. * @param onDismiss 바텀시트가 닫힐 때 호출되는 콜백 함수입니다. * @param onSaveClick 저장하기 버튼 클릭 시, 호출되는 콜백 함수입니다. - * @param initialSelectedOption 초기에 선택된 이미지를 나타내는 인덱스 값입니다. + * @param initialSelectedOption 초기에 선택된 이미지의 이름을 나타내는 string 값입니다. */ @OptIn(ExperimentalMaterial3Api::class) @Composable fun ProfileBottomSheet( modifier: Modifier = Modifier, onDismiss: () -> Unit, - onSaveClick: (Int) -> Unit, - initialSelectedOption: Int + onSaveClick: (ProfileImage) -> Unit, + initialSelectedOption: String ) { val scope = rememberCoroutineScope() val sheetState = rememberModalBottomSheetState() @@ -64,11 +65,11 @@ fun ProfileBottomSheet( ), ) RadioButtonGroup( - onOptionSelected = { index -> + onOptionSelected = { selectedProfile -> scope.launch { sheetState.hide() } .invokeOnCompletion { if (!sheetState.isVisible) { - onSaveClick(index) + onSaveClick(selectedProfile) } } }, @@ -82,29 +83,25 @@ fun ProfileBottomSheet( ) } + /** * 6개의 프로필 이미지 중, 하나의 이미지만 선택할 수 있는 라디오 버튼입니다. * - * @param onOptionSelected 선택된 이미지의 인덱스 값을 나타내는 콜백 함수입니다. - * @param initialSelectedOption 초기에 선택된 이미지를 나타내는 인덱스 값입니다. + * @param onOptionSelected 선택된 이미지의 이름을 나타내는 콜백 함수입니다. + * @param initialSelectedOption 초기에 선택된 이미지의 이름을 나타내는 string 값입니다. * @param modifier 라디오 버튼에 적용할 Modifier입니다. */ @Composable fun RadioButtonGroup( - onOptionSelected: (Int) -> Unit, - initialSelectedOption: Int, + onOptionSelected: (ProfileImage) -> Unit, + initialSelectedOption: String, modifier: Modifier = Modifier, ) { - val options = listOf( - R.drawable.ic_terning_profile_00, - R.drawable.ic_terning_profile_01, - R.drawable.ic_terning_profile_02, - R.drawable.ic_terning_profile_03, - R.drawable.ic_terning_profile_04, - R.drawable.ic_terning_profile_05 - ) + val options = ProfileImage.entries - var selectedOption by rememberSaveable { mutableIntStateOf(options[initialSelectedOption]) } + var selectedOptionIndex by rememberSaveable { + mutableIntStateOf(ProfileImage.toIndex(ProfileImage.fromString(initialSelectedOption))) + } LazyVerticalGrid( columns = GridCells.Fixed(3), @@ -112,8 +109,8 @@ fun RadioButtonGroup( horizontalArrangement = Arrangement.spacedBy(20.dp), modifier = modifier.padding(horizontal = 34.dp) ) { - itemsIndexed(options) { index, option -> - val imageModifier = if (selectedOption == options[index]) { + itemsIndexed(options.take(6)) { index, option -> + val imageModifier = if (selectedOptionIndex == index) { Modifier .border( color = TerningMain, @@ -126,14 +123,12 @@ fun RadioButtonGroup( } Image( - painter = painterResource( - id = option - ), + painter = painterResource(id = option.drawableResId), contentDescription = "profile image", modifier = imageModifier .noRippleClickable { - onOptionSelected(index) - selectedOption = option + onOptionSelected(option) + selectedOptionIndex = index } .clip(shape = CircleShape) .size(76.dp) @@ -141,4 +136,4 @@ fun RadioButtonGroup( ) } } -} \ No newline at end of file +} diff --git a/core/src/main/java/com/terning/core/designsystem/component/item/ProfileWithPlusButton.kt b/core/src/main/java/com/terning/core/designsystem/component/item/ProfileWithPlusButton.kt index 659f27b03..a8bccb6da 100644 --- a/core/src/main/java/com/terning/core/designsystem/component/item/ProfileWithPlusButton.kt +++ b/core/src/main/java/com/terning/core/designsystem/component/item/ProfileWithPlusButton.kt @@ -14,26 +14,20 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.terning.core.R +import com.terning.core.type.ProfileImage @Composable fun ProfileWithPlusButton( - index: Int, + profileImage: String, modifier: Modifier = Modifier, ) { - val grade = when (index) { - 0 -> R.drawable.ic_terning_profile_00 - 1 -> R.drawable.ic_terning_profile_01 - 2 -> R.drawable.ic_terning_profile_02 - 3 -> R.drawable.ic_terning_profile_03 - 4 -> R.drawable.ic_terning_profile_04 - else -> R.drawable.ic_terning_profile_05 - } + val userProfile = ProfileImage.fromString(profileImage) Box( modifier = modifier.wrapContentWidth() ) { Image( - painterResource(id = grade), + painterResource(id = userProfile.drawableResId), contentDescription = "profile image", modifier = modifier .clip(shape = CircleShape) @@ -51,5 +45,5 @@ fun ProfileWithPlusButton( @Preview(showBackground = true) @Composable fun ProfileWithPlusButtonPreview() { - ProfileWithPlusButton(index = 1) + ProfileWithPlusButton(profileImage = "basic") } \ No newline at end of file diff --git a/core/src/main/java/com/terning/core/designsystem/component/snackbar/TerningBasicSnackBar.kt b/core/src/main/java/com/terning/core/designsystem/component/snackbar/TerningBasicSnackBar.kt new file mode 100644 index 000000000..0d12f3811 --- /dev/null +++ b/core/src/main/java/com/terning/core/designsystem/component/snackbar/TerningBasicSnackBar.kt @@ -0,0 +1,23 @@ +package com.terning.core.designsystem.component.snackbar + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.unit.dp +import com.terning.core.designsystem.theme.Grey500 + +@Composable +fun TerningBasicSnackBar(content: @Composable () -> Unit) { + Box( + modifier = Modifier + .clip(CircleShape) + .background(Grey500) + .padding(vertical = 7.dp, horizontal = 20.dp) + ) { + content() + } +} \ No newline at end of file diff --git a/core/src/main/java/com/terning/core/type/ProfileImage.kt b/core/src/main/java/com/terning/core/type/ProfileImage.kt new file mode 100644 index 000000000..f4836df27 --- /dev/null +++ b/core/src/main/java/com/terning/core/type/ProfileImage.kt @@ -0,0 +1,33 @@ +package com.terning.core.type + +import androidx.annotation.DrawableRes +import com.terning.core.R + +enum class ProfileImage( + @DrawableRes val drawableResId: Int, + val stringValue: String +) { + + BASIC(drawableResId = R.drawable.ic_terning_profile_00, stringValue = "basic"), + LUCKY(drawableResId = R.drawable.ic_terning_profile_01, stringValue = "lucky"), + SMART(drawableResId = R.drawable.ic_terning_profile_02, stringValue = "smart"), + GLASS(drawableResId = R.drawable.ic_terning_profile_03, stringValue = "glass"), + CALENDAR(drawableResId = R.drawable.ic_terning_profile_04, stringValue = "calendar"), + PASSION(drawableResId = R.drawable.ic_terning_profile_05, stringValue = "passion"), + DEFAULT(drawableResId = R.drawable.ic_terning_profile_default, stringValue = "default"); + + companion object { + fun fromString(value: String): ProfileImage = when (value) { + "basic" -> BASIC + "lucky" -> LUCKY + "smart" -> SMART + "glass" -> GLASS + "calendar" -> CALENDAR + "passion" -> PASSION + else -> BASIC + } + + fun toIndex(profileImage: ProfileImage): Int = + entries.indexOf(profileImage) + } +} diff --git a/core/src/main/res/drawable/ic_terning_profile_00.xml b/core/src/main/res/drawable/ic_terning_profile_00.xml index f34f8769c..99edfdf96 100644 --- a/core/src/main/res/drawable/ic_terning_profile_00.xml +++ b/core/src/main/res/drawable/ic_terning_profile_00.xml @@ -1,137 +1,60 @@ - - - - - - - + android:width="76dp" + android:height="76dp" + android:viewportWidth="76" + android:viewportHeight="76"> + android:pathData="M38,0L38,0A38,38 0,0 1,76 38L76,38A38,38 0,0 1,38 76L38,76A38,38 0,0 1,0 38L0,38A38,38 0,0 1,38 0z"/> - - - - - - - - - - - - - - - - + android:pathData="M76,0H0V76H76V0Z" + android:fillColor="#FBF8CB"/> - - - - + android:pathData="M57.95,77.966L67.64,49.542C68.314,47.472 67.574,45.192 65.807,43.909L41.971,26.59C40.204,25.308 37.819,25.308 36.053,26.59L12.217,43.909C10.45,45.192 9.718,47.462 10.384,49.542L19.494,77.567C20.169,79.638 22.097,81.045 24.282,81.045H53.751" + android:fillColor="#ffffff"/> - - - - - - + android:pathData="M57.95,77.966L67.64,49.542C68.314,47.472 67.574,45.192 65.807,43.909L41.971,26.59C40.204,25.308 37.819,25.308 36.053,26.59L12.217,43.909C10.45,45.192 9.718,47.462 10.384,49.542L19.494,77.567C20.169,79.638 22.097,81.045 24.282,81.045H53.751" + android:strokeWidth="1.425" + android:fillColor="#00000000" + android:strokeColor="#171717" + android:strokeLineCap="round"/> + + + + + + + + + android:pathData="M35.444,53.884C35.444,53.884 36.243,55.613 38.114,55.613C39.986,55.613 40.565,53.884 40.565,53.884" + android:strokeWidth="1.425" + android:fillColor="#00000000" + android:strokeColor="#171717" + android:strokeLineCap="round"/> - diff --git a/core/src/main/res/drawable/ic_terning_profile_01.xml b/core/src/main/res/drawable/ic_terning_profile_01.xml index 557c169b6..0bfcc7b29 100644 --- a/core/src/main/res/drawable/ic_terning_profile_01.xml +++ b/core/src/main/res/drawable/ic_terning_profile_01.xml @@ -1,132 +1,80 @@ - - - - - - + android:width="76dp" + android:height="76dp" + android:viewportWidth="76" + android:viewportHeight="76"> + android:pathData="M38,0L38,0A38,38 0,0 1,76 38L76,38A38,38 0,0 1,38 76L38,76A38,38 0,0 1,0 38L0,38A38,38 0,0 1,38 0z"/> + android:pathData="M76,0H0V76H76V0Z" + android:fillColor="#ECF9CA"/> + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - diff --git a/core/src/main/res/drawable/ic_terning_profile_01_selected.png b/core/src/main/res/drawable/ic_terning_profile_01_selected.png deleted file mode 100644 index f85119d4b..000000000 Binary files a/core/src/main/res/drawable/ic_terning_profile_01_selected.png and /dev/null differ diff --git a/core/src/main/res/drawable/ic_terning_profile_02.xml b/core/src/main/res/drawable/ic_terning_profile_02.xml index 1ad3e5dd8..8ba5ffc15 100644 --- a/core/src/main/res/drawable/ic_terning_profile_02.xml +++ b/core/src/main/res/drawable/ic_terning_profile_02.xml @@ -1,98 +1,75 @@ - - - - - - + android:width="76dp" + android:height="76dp" + android:viewportWidth="76" + android:viewportHeight="76"> + android:pathData="M38,0L38,0A38,38 0,0 1,76 38L76,38A38,38 0,0 1,38 76L38,76A38,38 0,0 1,0 38L0,38A38,38 0,0 1,38 0z"/> + android:pathData="M76,0H0V76H76V0Z" + android:fillColor="#D4F9DE"/> + + + + + + + + + + + + + - - - - - - - - - - - - - - diff --git a/core/src/main/res/drawable/ic_terning_profile_03.xml b/core/src/main/res/drawable/ic_terning_profile_03.xml index fc45cad6a..25e878efb 100644 --- a/core/src/main/res/drawable/ic_terning_profile_03.xml +++ b/core/src/main/res/drawable/ic_terning_profile_03.xml @@ -1,131 +1,76 @@ - - - - - + android:width="76dp" + android:height="76dp" + android:viewportWidth="76" + android:viewportHeight="76"> + android:pathData="M38,0L38,0A38,38 0,0 1,76 38L76,38A38,38 0,0 1,38 76L38,76A38,38 0,0 1,0 38L0,38A38,38 0,0 1,38 0z"/> + android:pathData="M76.209,0H0.209V76H76.209V0Z" + android:fillColor="#C5DEF2"/> + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - diff --git a/core/src/main/res/drawable/ic_terning_profile_04.xml b/core/src/main/res/drawable/ic_terning_profile_04.xml index 228909ea8..8b27c5c6c 100644 --- a/core/src/main/res/drawable/ic_terning_profile_04.xml +++ b/core/src/main/res/drawable/ic_terning_profile_04.xml @@ -1,150 +1,74 @@ + android:width="76dp" + android:height="76dp" + android:viewportWidth="76" + android:viewportHeight="76"> + android:pathData="M76,0H0V76H76V0Z" + android:fillColor="#E9F1E4"/> - - - - - - - - - - - - - - - - - - - - - - + android:pathData="M64.676,32.956H11.324V85.035H64.676V32.956Z" + android:strokeLineJoin="round" + android:strokeWidth="1.425" + android:fillColor="#ffffff" + android:strokeColor="#171717" + android:strokeLineCap="round"/> + android:pathData="M31.663,53.447C31.663,53.779 31.616,54.131 31.502,54.416C31.388,54.701 31.036,54.872 30.808,55.1C30.58,55.328 30.409,55.623 30.105,55.746C29.801,55.869 29.488,55.841 29.155,55.841C28.823,55.841 28.509,55.822 28.224,55.699C27.939,55.575 27.654,55.395 27.426,55.167C27.198,54.938 26.999,54.682 26.875,54.378C26.752,54.074 26.638,53.761 26.638,53.438C26.638,53.114 26.837,52.811 26.961,52.526C27.084,52.241 27.274,52.003 27.502,51.775C27.73,51.547 27.939,51.319 28.234,51.195C28.528,51.072 28.832,51.072 29.165,51.072C29.497,51.072 29.801,51.082 30.086,51.205C30.371,51.328 30.647,51.509 30.875,51.728C31.103,51.946 31.293,52.212 31.416,52.507C31.54,52.801 31.682,53.105 31.682,53.438L31.663,53.447Z" + android:fillColor="#F9DBDE"/> + android:pathData="M31.663,53.447C31.663,53.779 31.616,54.131 31.502,54.416C31.388,54.701 31.036,54.872 30.808,55.1C30.58,55.328 30.409,55.623 30.105,55.746C29.801,55.869 29.488,55.841 29.155,55.841C28.823,55.841 28.509,55.822 28.224,55.699C27.939,55.575 27.654,55.395 27.426,55.167C27.198,54.938 26.999,54.682 26.875,54.378C26.752,54.074 26.638,53.761 26.638,53.438C26.638,53.114 26.837,52.811 26.961,52.526C27.084,52.241 27.274,52.003 27.502,51.775C27.73,51.547 27.939,51.319 28.234,51.195C28.528,51.072 28.832,51.072 29.165,51.072C29.497,51.072 29.801,51.082 30.086,51.205C30.371,51.328 30.647,51.509 30.875,51.728C31.103,51.946 31.293,52.212 31.416,52.507C31.54,52.801 31.682,53.105 31.682,53.438L31.663,53.447Z" + android:strokeWidth="0.7315" + android:fillColor="#00000000" + android:strokeColor="#F9DBDE"/> + android:pathData="M49.343,53.267C49.343,53.599 49.267,53.932 49.143,54.226C49.02,54.521 48.839,54.825 48.611,55.043C48.383,55.262 48.079,55.433 47.785,55.556C47.49,55.68 47.167,55.651 46.835,55.651C46.502,55.651 46.217,55.585 45.923,55.461C45.628,55.338 45.267,55.281 45.049,55.053C44.83,54.825 44.669,54.511 44.545,54.217C44.422,53.922 44.422,53.599 44.422,53.267C44.422,52.934 44.45,52.611 44.564,52.326C44.678,52.041 44.897,51.775 45.125,51.557C45.353,51.338 45.638,51.215 45.932,51.091C46.227,50.968 46.502,50.92 46.835,50.92C47.167,50.92 47.49,50.863 47.785,50.987C48.079,51.11 48.355,51.3 48.583,51.528C48.811,51.756 49.01,52.022 49.134,52.326C49.257,52.63 49.343,52.944 49.343,53.276V53.267Z" + android:fillColor="#F9DBDE"/> + android:strokeColor="#F9DBDE"/> + android:pathData="M37.506,63.441H38.598C38.988,63.441 39.32,63.707 39.396,64.077L41.762,75.8C41.828,76.199 41.705,76.608 41.42,76.902L39.016,79.372C38.503,79.895 37.648,79.914 37.126,79.401L34.618,76.978C34.314,76.684 34.171,76.256 34.247,75.838L36.717,64.077C36.793,63.707 37.126,63.441 37.515,63.441H37.506Z" + android:strokeWidth="1.425" + android:fillColor="#A6B7FF" + android:strokeColor="#171717"/> + android:pathData="M39.168,63.907H36.955C36.518,63.907 36.147,63.603 36.053,63.185L35.54,60.952C35.407,60.373 35.853,59.812 36.442,59.812H39.701C40.299,59.812 40.745,60.373 40.603,60.952L40.071,63.185C39.976,63.603 39.596,63.897 39.168,63.897V63.907Z" + android:strokeWidth="1.425" + android:fillColor="#A6B7FF" + android:strokeColor="#171717"/> + android:pathData="M34.818,52.497C35.384,52.497 35.843,51.791 35.843,50.92C35.843,50.049 35.384,49.343 34.818,49.343C34.251,49.343 33.792,50.049 33.792,50.92C33.792,51.791 34.251,52.497 34.818,52.497Z" + android:fillColor="#171717"/> + android:pathData="M41.182,52.497C41.749,52.497 42.208,51.791 42.208,50.92C42.208,50.049 41.749,49.343 41.182,49.343C40.616,49.343 40.157,50.049 40.157,50.92C40.157,51.791 40.616,52.497 41.182,52.497Z" + android:fillColor="#171717"/> + diff --git a/core/src/main/res/drawable/ic_terning_profile_05.xml b/core/src/main/res/drawable/ic_terning_profile_05.xml index 2d21f7990..9a32c789e 100644 --- a/core/src/main/res/drawable/ic_terning_profile_05.xml +++ b/core/src/main/res/drawable/ic_terning_profile_05.xml @@ -1,111 +1,73 @@ - - - - + android:width="76dp" + android:height="76dp" + android:viewportWidth="76" + android:viewportHeight="76"> + android:pathData="M38,0L38,0A38,38 0,0 1,76 38L76,38A38,38 0,0 1,38 76L38,76A38,38 0,0 1,0 38L0,38A38,38 0,0 1,38 0z"/> + android:pathData="M76,0H0V76H76V0Z" + android:fillColor="#E6FFF6"/> + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - diff --git a/core/src/main/res/drawable/ic_terning_profile_default.xml b/core/src/main/res/drawable/ic_terning_profile_default.xml new file mode 100644 index 000000000..e3a32368c --- /dev/null +++ b/core/src/main/res/drawable/ic_terning_profile_default.xml @@ -0,0 +1,9 @@ + + + diff --git a/data/src/main/java/com/terning/data/datasource/MyPageDataSource.kt b/data/src/main/java/com/terning/data/datasource/MyPageDataSource.kt index 5eee61e1b..60361d5f2 100644 --- a/data/src/main/java/com/terning/data/datasource/MyPageDataSource.kt +++ b/data/src/main/java/com/terning/data/datasource/MyPageDataSource.kt @@ -2,6 +2,7 @@ package com.terning.data.datasource import com.terning.data.dto.BaseResponse import com.terning.data.dto.NonDataBaseResponse +import com.terning.data.dto.request.MyPageProfileEditRequestDto import com.terning.data.dto.response.MyPageResponseDto interface MyPageDataSource { @@ -10,4 +11,8 @@ interface MyPageDataSource { suspend fun deleteQuit(): NonDataBaseResponse suspend fun getProfile(): BaseResponse + + suspend fun editProfile( + request: MyPageProfileEditRequestDto + ): NonDataBaseResponse } \ No newline at end of file diff --git a/data/src/main/java/com/terning/data/datasourceimpl/MyPageDataSourceImpl.kt b/data/src/main/java/com/terning/data/datasourceimpl/MyPageDataSourceImpl.kt index d1636d0d5..bc96ce7b0 100644 --- a/data/src/main/java/com/terning/data/datasourceimpl/MyPageDataSourceImpl.kt +++ b/data/src/main/java/com/terning/data/datasourceimpl/MyPageDataSourceImpl.kt @@ -3,6 +3,7 @@ package com.terning.data.datasourceimpl import com.terning.data.datasource.MyPageDataSource import com.terning.data.dto.BaseResponse import com.terning.data.dto.NonDataBaseResponse +import com.terning.data.dto.request.MyPageProfileEditRequestDto import com.terning.data.dto.response.MyPageResponseDto import com.terning.data.service.MyPageService import javax.inject.Inject @@ -15,4 +16,8 @@ class MyPageDataSourceImpl @Inject constructor( override suspend fun deleteQuit(): NonDataBaseResponse = myPageService.deleteQuit() override suspend fun getProfile(): BaseResponse = myPageService.getProfile() + + override suspend fun editProfile( + request: MyPageProfileEditRequestDto + ): NonDataBaseResponse = myPageService.editProfile() } \ No newline at end of file diff --git a/data/src/main/java/com/terning/data/dto/request/MyPageProfileEditRequestDto.kt b/data/src/main/java/com/terning/data/dto/request/MyPageProfileEditRequestDto.kt new file mode 100644 index 000000000..3f4c7ef8a --- /dev/null +++ b/data/src/main/java/com/terning/data/dto/request/MyPageProfileEditRequestDto.kt @@ -0,0 +1,12 @@ +package com.terning.data.dto.request + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class MyPageProfileEditRequestDto( + @SerialName("name") + val name: String, + @SerialName("profileImage") + val profileImage: String, +) \ No newline at end of file diff --git a/data/src/main/java/com/terning/data/dto/request/SignUpRequestDto.kt b/data/src/main/java/com/terning/data/dto/request/SignUpRequestDto.kt index fbfc3d0bf..9cea3722d 100644 --- a/data/src/main/java/com/terning/data/dto/request/SignUpRequestDto.kt +++ b/data/src/main/java/com/terning/data/dto/request/SignUpRequestDto.kt @@ -8,7 +8,7 @@ data class SignUpRequestDto( @SerialName("name") val name: String, @SerialName("profileImage") - val profileImage: Int, + val profileImage: String, @SerialName("authType") val authType: String ) \ No newline at end of file diff --git a/data/src/main/java/com/terning/data/dto/response/MyPageResponseDto.kt b/data/src/main/java/com/terning/data/dto/response/MyPageResponseDto.kt index 035919f84..3afedf5b3 100644 --- a/data/src/main/java/com/terning/data/dto/response/MyPageResponseDto.kt +++ b/data/src/main/java/com/terning/data/dto/response/MyPageResponseDto.kt @@ -7,6 +7,8 @@ import kotlinx.serialization.Serializable data class MyPageResponseDto( @SerialName("name") val name: String, + @SerialName("profileImage") + val profileImage: String, @SerialName("authType") val authType: String ) \ No newline at end of file diff --git a/data/src/main/java/com/terning/data/mapper/mypage/MyPageMapper.kt b/data/src/main/java/com/terning/data/mapper/mypage/MyPageMapper.kt index 2ae84fa1b..0a19f6e76 100644 --- a/data/src/main/java/com/terning/data/mapper/mypage/MyPageMapper.kt +++ b/data/src/main/java/com/terning/data/mapper/mypage/MyPageMapper.kt @@ -1,6 +1,11 @@ package com.terning.data.mapper.mypage import com.terning.data.dto.response.MyPageResponseDto -import com.terning.domain.entity.mypage.MyPageProfileModel +import com.terning.domain.entity.mypage.MyPageProfile -fun MyPageResponseDto.toMyPageProfile() = MyPageProfileModel(name = name, authType = authType) +fun MyPageResponseDto.toMyPageProfile() = + MyPageProfile( + name = name, + profileImage = profileImage, + authType = authType + ) diff --git a/data/src/main/java/com/terning/data/mapper/mypage/MyPageProfileEditMapper.kt b/data/src/main/java/com/terning/data/mapper/mypage/MyPageProfileEditMapper.kt new file mode 100644 index 000000000..892bbd425 --- /dev/null +++ b/data/src/main/java/com/terning/data/mapper/mypage/MyPageProfileEditMapper.kt @@ -0,0 +1,10 @@ +package com.terning.data.mapper.mypage + +import com.terning.data.dto.request.MyPageProfileEditRequestDto +import com.terning.domain.entity.mypage.MyPageProfileEdit + +fun MyPageProfileEdit.toMyPageProfileEditRequestDto(): MyPageProfileEditRequestDto = + MyPageProfileEditRequestDto( + name = name, + profileImage = profileImage + ) diff --git a/data/src/main/java/com/terning/data/repositoryimpl/MyPageRepositoryImpl.kt b/data/src/main/java/com/terning/data/repositoryimpl/MyPageRepositoryImpl.kt index 45cafad9b..76aa84af2 100644 --- a/data/src/main/java/com/terning/data/repositoryimpl/MyPageRepositoryImpl.kt +++ b/data/src/main/java/com/terning/data/repositoryimpl/MyPageRepositoryImpl.kt @@ -2,7 +2,9 @@ package com.terning.data.repositoryimpl import com.terning.data.datasource.MyPageDataSource import com.terning.data.mapper.mypage.toMyPageProfile -import com.terning.domain.entity.mypage.MyPageProfileModel +import com.terning.data.mapper.mypage.toMyPageProfileEditRequestDto +import com.terning.domain.entity.mypage.MyPageProfile +import com.terning.domain.entity.mypage.MyPageProfileEdit import com.terning.domain.repository.MyPageRepository import javax.inject.Inject @@ -19,8 +21,17 @@ class MyPageRepositoryImpl @Inject constructor( myPageDataSource.deleteQuit() } - override suspend fun getProfile(): Result = + override suspend fun getProfile(): Result = runCatching { myPageDataSource.getProfile().result.toMyPageProfile() } + + override suspend fun editProfile( + request: MyPageProfileEdit + ): Result = + runCatching { + myPageDataSource.editProfile( + request.toMyPageProfileEditRequestDto() + ) + } } \ No newline at end of file diff --git a/data/src/main/java/com/terning/data/service/MyPageService.kt b/data/src/main/java/com/terning/data/service/MyPageService.kt index 26a7d76ca..6ce2d16ae 100644 --- a/data/src/main/java/com/terning/data/service/MyPageService.kt +++ b/data/src/main/java/com/terning/data/service/MyPageService.kt @@ -5,6 +5,7 @@ import com.terning.data.dto.NonDataBaseResponse import com.terning.data.dto.response.MyPageResponseDto import retrofit2.http.DELETE import retrofit2.http.GET +import retrofit2.http.PATCH import retrofit2.http.POST interface MyPageService { @@ -16,4 +17,7 @@ interface MyPageService { @GET("api/v1/mypage/profile") suspend fun getProfile(): BaseResponse + + @PATCH("api/v1/mypage/profile") + suspend fun editProfile(): NonDataBaseResponse } \ No newline at end of file diff --git a/domain/src/main/java/com/terning/domain/entity/mypage/MyPageProfileModel.kt b/domain/src/main/java/com/terning/domain/entity/mypage/MyPageProfile.kt similarity index 61% rename from domain/src/main/java/com/terning/domain/entity/mypage/MyPageProfileModel.kt rename to domain/src/main/java/com/terning/domain/entity/mypage/MyPageProfile.kt index 9576d68dc..356758d3e 100644 --- a/domain/src/main/java/com/terning/domain/entity/mypage/MyPageProfileModel.kt +++ b/domain/src/main/java/com/terning/domain/entity/mypage/MyPageProfile.kt @@ -1,6 +1,7 @@ package com.terning.domain.entity.mypage -data class MyPageProfileModel( +data class MyPageProfile( val name: String, + val profileImage: String, val authType: String ) \ No newline at end of file diff --git a/domain/src/main/java/com/terning/domain/entity/mypage/MyPageProfileEdit.kt b/domain/src/main/java/com/terning/domain/entity/mypage/MyPageProfileEdit.kt new file mode 100644 index 000000000..398575b04 --- /dev/null +++ b/domain/src/main/java/com/terning/domain/entity/mypage/MyPageProfileEdit.kt @@ -0,0 +1,6 @@ +package com.terning.domain.entity.mypage + +data class MyPageProfileEdit( + val name: String, + val profileImage: String +) \ No newline at end of file diff --git a/domain/src/main/java/com/terning/domain/entity/onboarding/SignUpRequest.kt b/domain/src/main/java/com/terning/domain/entity/onboarding/SignUpRequest.kt index 7b24e160e..dc74f8bdb 100644 --- a/domain/src/main/java/com/terning/domain/entity/onboarding/SignUpRequest.kt +++ b/domain/src/main/java/com/terning/domain/entity/onboarding/SignUpRequest.kt @@ -2,6 +2,6 @@ package com.terning.domain.entity.onboarding data class SignUpRequest ( val name : String, - val profileImage : Int, + val profileImage : String, val authType : String ) \ No newline at end of file diff --git a/domain/src/main/java/com/terning/domain/repository/MyPageRepository.kt b/domain/src/main/java/com/terning/domain/repository/MyPageRepository.kt index 26eaed11f..917b82c17 100644 --- a/domain/src/main/java/com/terning/domain/repository/MyPageRepository.kt +++ b/domain/src/main/java/com/terning/domain/repository/MyPageRepository.kt @@ -1,11 +1,16 @@ package com.terning.domain.repository -import com.terning.domain.entity.mypage.MyPageProfileModel +import com.terning.domain.entity.mypage.MyPageProfile +import com.terning.domain.entity.mypage.MyPageProfileEdit interface MyPageRepository { suspend fun postLogout(): Result suspend fun deleteQuit(): Result - suspend fun getProfile(): Result + suspend fun getProfile(): Result + + suspend fun editProfile( + request: MyPageProfileEdit + ): Result } \ No newline at end of file diff --git a/feature/src/main/java/com/terning/feature/main/MainNavigator.kt b/feature/src/main/java/com/terning/feature/main/MainNavigator.kt index f0598bf1f..8455eb2a6 100644 --- a/feature/src/main/java/com/terning/feature/main/MainNavigator.kt +++ b/feature/src/main/java/com/terning/feature/main/MainNavigator.kt @@ -31,9 +31,12 @@ class MainNavigator( fun navigate(tab: MainTab) { val navOptions = navOptions { - popUpTo(navController.graph.findStartDestination().id) { - saveState = true - } + navController.currentDestination?.route?.let { + popUpTo(it){ + inclusive = true + saveState = true + } + } launchSingleTop = true restoreState = true } diff --git a/feature/src/main/java/com/terning/feature/main/MainScreen.kt b/feature/src/main/java/com/terning/feature/main/MainScreen.kt index 6403b2e31..516f63bf1 100644 --- a/feature/src/main/java/com/terning/feature/main/MainScreen.kt +++ b/feature/src/main/java/com/terning/feature/main/MainScreen.kt @@ -1,5 +1,7 @@ package com.terning.feature.main +import android.app.Activity +import androidx.activity.compose.BackHandler import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.EnterTransition import androidx.compose.animation.ExitTransition @@ -13,14 +15,24 @@ import androidx.compose.material3.Icon import androidx.compose.material3.NavigationBar import androidx.compose.material3.NavigationBarItem import androidx.compose.material3.Scaffold +import androidx.compose.material3.SnackbarDuration +import androidx.compose.material3.SnackbarHost +import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.Text 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.Modifier +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.sp import androidx.navigation.compose.NavHost +import com.terning.core.designsystem.component.snackbar.TerningBasicSnackBar import com.terning.core.designsystem.theme.Grey300 import com.terning.core.designsystem.theme.TerningMain import com.terning.core.designsystem.theme.White @@ -41,12 +53,45 @@ import com.terning.feature.onboarding.signup.navigation.signUpNavGraph import com.terning.feature.onboarding.splash.navigation.splashNavGraph import com.terning.feature.search.search.navigation.searchNavGraph import com.terning.feature.search.searchprocess.navigation.searchProcessNavGraph +import kotlinx.coroutines.launch @Composable fun MainScreen( navigator: MainNavigator = rememberMainNavigator(), ) { + val context = LocalContext.current + var backPressedState by remember { mutableStateOf(true) } + var backPressedTime = 0L + + val snackBarHostState = remember { SnackbarHostState() } + val coroutineScope = rememberCoroutineScope() + + BackHandler(enabled = backPressedState) { + if (System.currentTimeMillis() - backPressedTime <= 3000) { + (context as Activity).finish() + } else { + backPressedState = true + coroutineScope.launch { + snackBarHostState.showSnackbar( + message = "버튼을 한 번 더 누르면 종료돼요", + duration = SnackbarDuration.Short + ) + } + } + backPressedTime = System.currentTimeMillis() + } + Scaffold( + snackbarHost = { + SnackbarHost(hostState = snackBarHostState) { snackBarData -> + TerningBasicSnackBar { + Text( + text = snackBarData.visuals.message, + color = White, + ) + } + } + }, bottomBar = { MainBottomBar( isVisible = navigator.showBottomBar(), diff --git a/feature/src/main/java/com/terning/feature/mypage/mypage/MyPageRoute.kt b/feature/src/main/java/com/terning/feature/mypage/mypage/MyPageRoute.kt index e520d3504..4ec22dbcc 100644 --- a/feature/src/main/java/com/terning/feature/mypage/mypage/MyPageRoute.kt +++ b/feature/src/main/java/com/terning/feature/mypage/mypage/MyPageRoute.kt @@ -15,6 +15,7 @@ import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Text import androidx.compose.material3.VerticalDivider import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.SideEffect import androidx.compose.runtime.getValue @@ -40,6 +41,7 @@ import com.terning.core.designsystem.theme.TerningPointTheme import com.terning.core.designsystem.theme.TerningTheme import com.terning.core.designsystem.theme.White import com.terning.core.extension.noRippleClickable +import com.terning.core.extension.toast import com.terning.core.state.UiState import com.terning.feature.R import com.terning.feature.mypage.component.MyPageProfile @@ -48,7 +50,7 @@ import com.terning.feature.mypage.mypage.component.MyPageItem @Composable fun MyPageRoute( paddingValues: PaddingValues, - navigateToProfileEdit: (String, Int) -> Unit, + navigateToProfileEdit: (String, String) -> Unit, viewModel: MyPageViewModel = hiltViewModel(), ) { val state by viewModel.state.collectAsStateWithLifecycle() @@ -63,14 +65,24 @@ fun MyPageRoute( ) } + DisposableEffect(lifecycleOwner) { + onDispose { + systemUiController.setStatusBarColor( + color = White + ) + } + } + LaunchedEffect(viewModel.sideEffects, lifecycleOwner) { viewModel.sideEffects.flowWithLifecycle(lifecycle = lifecycleOwner.lifecycle) .collect { sideEffect -> when (sideEffect) { is MyPageSideEffect.NavigateToProfileEdit -> navigateToProfileEdit( state.name, - state.profile + state.profileImage ) + + is MyPageSideEffect.ShowToast -> context.toast(sideEffect.message) } } } @@ -115,13 +127,18 @@ fun MyPageRoute( onServiceClick = {}, onPersonalClick = {}, name = state.name, - profile = state.profile + profileImage = state.profileImage ) } is UiState.Loading -> {} is UiState.Empty -> {} - is UiState.Failure -> {} + is UiState.Failure -> { + MyPageScreen( + paddingValues = paddingValues, + profileImage = state.profileImage, + ) + } } if (state.showNotice) { @@ -137,16 +154,16 @@ fun MyPageRoute( @Composable fun MyPageScreen( - onEditClick: () -> Unit, - onLogoutClick: () -> Unit, - onQuitClick: () -> Unit, - onNoticeClick: () -> Unit, - onOpinionClick: () -> Unit, - onServiceClick: () -> Unit, - onPersonalClick: () -> Unit, + onEditClick: () -> Unit = {}, + onLogoutClick: () -> Unit = {}, + onQuitClick: () -> Unit = {}, + onNoticeClick: () -> Unit = {}, + onOpinionClick: () -> Unit = {}, + onServiceClick: () -> Unit = {}, + onPersonalClick: () -> Unit = {}, paddingValues: PaddingValues = PaddingValues(), name: String = "", - profile: Int = 0 + profileImage: String = "" ) { Column( modifier = Modifier @@ -156,7 +173,7 @@ fun MyPageScreen( ) { UserProfile( name = name, - profile = profile, + profileImage = profileImage, onEditClick = onEditClick ) TerningCommunity( @@ -209,7 +226,7 @@ fun UserProfile( name: String, onEditClick: () -> Unit, modifier: Modifier = Modifier, - profile: Int = 0, + profileImage: String = "", ) { Row( modifier = modifier.padding( @@ -218,7 +235,7 @@ fun UserProfile( bottom = 32.dp ) ) { - MyPageProfile(profile = profile) + MyPageProfile(profileImage = profileImage) Column { Text( text = name, diff --git a/feature/src/main/java/com/terning/feature/mypage/mypage/MyPageSideEffect.kt b/feature/src/main/java/com/terning/feature/mypage/mypage/MyPageSideEffect.kt index 26d1e5856..edeb627ea 100644 --- a/feature/src/main/java/com/terning/feature/mypage/mypage/MyPageSideEffect.kt +++ b/feature/src/main/java/com/terning/feature/mypage/mypage/MyPageSideEffect.kt @@ -1,5 +1,8 @@ package com.terning.feature.mypage.mypage +import androidx.annotation.StringRes + sealed class MyPageSideEffect { data object NavigateToProfileEdit : MyPageSideEffect() + data class ShowToast(@StringRes val message: Int) : MyPageSideEffect() } \ No newline at end of file diff --git a/feature/src/main/java/com/terning/feature/mypage/mypage/MyPageState.kt b/feature/src/main/java/com/terning/feature/mypage/mypage/MyPageState.kt index bf072cb13..24f76c1ae 100644 --- a/feature/src/main/java/com/terning/feature/mypage/mypage/MyPageState.kt +++ b/feature/src/main/java/com/terning/feature/mypage/mypage/MyPageState.kt @@ -6,7 +6,7 @@ data class MyPageState( val isLogoutAndQuitSuccess: UiState = UiState.Loading, val isGetSuccess: UiState = UiState.Loading, val name: String = "", - val profile: Int = 0, + val profileImage: String = "", val authType : String ="", val showNotice: Boolean = false, val showOpinion: Boolean = false, diff --git a/feature/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt b/feature/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt index b4f39bb61..535cf4b6d 100644 --- a/feature/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt +++ b/feature/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt @@ -13,6 +13,7 @@ import com.kakao.sdk.user.UserApiClient import com.terning.core.state.UiState import com.terning.domain.repository.MyPageRepository import com.terning.domain.repository.TokenRepository +import com.terning.feature.R import com.terning.feature.main.MainActivity import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableSharedFlow @@ -104,9 +105,11 @@ class MyPageViewModel @Inject constructor( _state.value = _state.value.copy( isGetSuccess = UiState.Success(true), name = response.name, + profileImage = response.profileImage, authType = response.authType ) }.onFailure { + _sideEffects.emit(MyPageSideEffect.ShowToast(R.string.server_failure)) _state.value = _state.value.copy(isGetSuccess = UiState.Failure(it.toString())) } } diff --git a/feature/src/main/java/com/terning/feature/mypage/mypage/component/MyPageProfile.kt b/feature/src/main/java/com/terning/feature/mypage/mypage/component/MyPageProfile.kt index cd12d2623..a0d985004 100644 --- a/feature/src/main/java/com/terning/feature/mypage/mypage/component/MyPageProfile.kt +++ b/feature/src/main/java/com/terning/feature/mypage/mypage/component/MyPageProfile.kt @@ -10,36 +10,21 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import com.terning.core.R +import com.terning.core.type.ProfileImage @Composable fun MyPageProfile( modifier: Modifier = Modifier, - profile: Int + profileImage: String ) { - val options = listOf( - R.drawable.ic_terning_profile_00, - R.drawable.ic_terning_profile_01, - R.drawable.ic_terning_profile_02, - R.drawable.ic_terning_profile_03, - R.drawable.ic_terning_profile_04, - R.drawable.ic_terning_profile_05 - ) - - val option = when (profile) { - 0 -> options[0] - 1 -> options[1] - 2 -> options[2] - 3 -> options[3] - 4 -> options[4] - else -> options[5] - } + val userProfile = ProfileImage.fromString(profileImage) Image( - painter = painterResource(id = option), + painter = painterResource(id = userProfile.drawableResId), modifier = modifier .size(72.dp) .clip(shape = CircleShape) .aspectRatio(1f), contentDescription = "profile image" ) -} +} \ No newline at end of file diff --git a/feature/src/main/java/com/terning/feature/mypage/mypage/navigation/MyPageNavigation.kt b/feature/src/main/java/com/terning/feature/mypage/mypage/navigation/MyPageNavigation.kt index 7248c8a2a..e2543a085 100644 --- a/feature/src/main/java/com/terning/feature/mypage/mypage/navigation/MyPageNavigation.kt +++ b/feature/src/main/java/com/terning/feature/mypage/mypage/navigation/MyPageNavigation.kt @@ -25,10 +25,10 @@ fun NavGraphBuilder.myPageNavGraph( composable { MyPageRoute( paddingValues = paddingValues, - navigateToProfileEdit = { name, profile -> + navigateToProfileEdit = { name, profileImage -> navHostController.navigateProfileEdit( name, - profile + profileImage ) } ) diff --git a/feature/src/main/java/com/terning/feature/mypage/profileedit/ProfileEditRoute.kt b/feature/src/main/java/com/terning/feature/mypage/profileedit/ProfileEditRoute.kt index 577c5689b..7dba0d325 100644 --- a/feature/src/main/java/com/terning/feature/mypage/profileedit/ProfileEditRoute.kt +++ b/feature/src/main/java/com/terning/feature/mypage/profileedit/ProfileEditRoute.kt @@ -15,6 +15,7 @@ import androidx.compose.runtime.SideEffect import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview @@ -35,18 +36,20 @@ import com.terning.core.designsystem.theme.TerningTheme import com.terning.core.designsystem.theme.White import com.terning.core.extension.addFocusCleaner import com.terning.core.extension.noRippleClickable +import com.terning.core.extension.toast import com.terning.feature.R @Composable fun ProfileEditRoute( navigateUp: () -> Unit, initialName: String, - initialProfile: Int, + initialProfile: String, viewModel: ProfileEditViewModel = hiltViewModel(), ) { val state by viewModel.state.collectAsStateWithLifecycle() val lifecycleOwner = LocalLifecycleOwner.current + val context = LocalContext.current val systemUiController = rememberSystemUiController() @@ -57,7 +60,10 @@ fun ProfileEditRoute( } LaunchedEffect(key1 = true) { - viewModel.updateInitialInfo(initialName = initialName, initialProfile = initialProfile) + viewModel.updateInitialInfo( + initialName = initialName, + initialProfile = initialProfile + ) } LaunchedEffect(viewModel.sideEffects, lifecycleOwner) { @@ -65,6 +71,7 @@ fun ProfileEditRoute( .collect { sideEffect -> when (sideEffect) { is ProfileEditSideEffect.NavigateUp -> navigateUp() + is ProfileEditSideEffect.ShowToast -> context.toast(sideEffect.message) } } } @@ -72,9 +79,9 @@ fun ProfileEditRoute( if (state.showBottomSheet) { ProfileBottomSheet( onDismiss = { viewModel.updateBottomSheet(false) }, - onSaveClick = { index -> + onSaveClick = { profileImage -> viewModel.updateBottomSheet(false) - viewModel.updateProfile(index) + viewModel.updateProfile(profileImage.stringValue) }, initialSelectedOption = state.profile ) @@ -88,7 +95,9 @@ fun ProfileEditRoute( onInputChange = { editName -> viewModel.updateName(editName) }, - onSaveClick = { viewModel.navigateUp() }, + onSaveClick = { + viewModel.modifyUserInfo() + }, name = state.name, onBackButtonClick = { viewModel.navigateUp() }, onValidationChanged = { isValid -> @@ -137,7 +146,7 @@ fun ProfileEditScreen( onProfileEditClick(true) } .align(Alignment.CenterHorizontally), - index = profileEditState.profile + profileImage = profileEditState.profile ) Spacer(modifier = Modifier.height(48.dp)) Text( diff --git a/feature/src/main/java/com/terning/feature/mypage/profileedit/ProfileEditSideEffect.kt b/feature/src/main/java/com/terning/feature/mypage/profileedit/ProfileEditSideEffect.kt index 6fd2f3668..9d16e2bc8 100644 --- a/feature/src/main/java/com/terning/feature/mypage/profileedit/ProfileEditSideEffect.kt +++ b/feature/src/main/java/com/terning/feature/mypage/profileedit/ProfileEditSideEffect.kt @@ -1,5 +1,8 @@ package com.terning.feature.mypage.profileedit +import androidx.annotation.StringRes + sealed class ProfileEditSideEffect { data object NavigateUp : ProfileEditSideEffect() + data class ShowToast(@StringRes val message: Int) : ProfileEditSideEffect() } \ No newline at end of file diff --git a/feature/src/main/java/com/terning/feature/mypage/profileedit/ProfileEditState.kt b/feature/src/main/java/com/terning/feature/mypage/profileedit/ProfileEditState.kt index eb34b9548..a8f1d2b96 100644 --- a/feature/src/main/java/com/terning/feature/mypage/profileedit/ProfileEditState.kt +++ b/feature/src/main/java/com/terning/feature/mypage/profileedit/ProfileEditState.kt @@ -3,7 +3,7 @@ package com.terning.feature.mypage.profileedit data class ProfileEditState( val name: String = "", val initialName: String = "", - val profile: Int = 0, + val profile: String = "", val initialView: Boolean = true, val isButtonValid: Boolean = false, val authType: String = "", diff --git a/feature/src/main/java/com/terning/feature/mypage/profileedit/ProfileEditViewModel.kt b/feature/src/main/java/com/terning/feature/mypage/profileedit/ProfileEditViewModel.kt index 58bf6349f..5516b79c2 100644 --- a/feature/src/main/java/com/terning/feature/mypage/profileedit/ProfileEditViewModel.kt +++ b/feature/src/main/java/com/terning/feature/mypage/profileedit/ProfileEditViewModel.kt @@ -2,6 +2,9 @@ package com.terning.feature.mypage.profileedit import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import com.terning.domain.entity.mypage.MyPageProfileEdit +import com.terning.domain.repository.MyPageRepository +import com.terning.feature.R import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow @@ -13,7 +16,9 @@ import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel -class ProfileEditViewModel @Inject constructor() : ViewModel() { +class ProfileEditViewModel @Inject constructor( + private val myPageRepository: MyPageRepository, +) : ViewModel() { private val _state: MutableStateFlow = MutableStateFlow(ProfileEditState()) val state: StateFlow get() = _state.asStateFlow() @@ -27,7 +32,7 @@ class ProfileEditViewModel @Inject constructor() : ViewModel() { _state.value = _state.value.copy(showBottomSheet = isVisible) } - fun updateInitialInfo(initialName: String, initialProfile: Int) { + fun updateInitialInfo(initialName: String, initialProfile: String) { _state.value = _state.value.copy( name = initialName, initialName = initialName, @@ -36,15 +41,36 @@ class ProfileEditViewModel @Inject constructor() : ViewModel() { } fun updateName(name: String) { - _state.value = _state.value.copy(name = name, initialView = false) + _state.value = _state.value.copy( + name = name, + initialView = false + ) } - fun updateProfile(profile: Int) { - _state.value = _state.value.copy(profile = profile, initialView = false) + fun updateProfile(profile: String) { + _state.value = _state.value.copy( + profile = profile, + initialView = false + ) } fun updateButtonValidation(isValid: Boolean) { _state.value = _state.value.copy(isButtonValid = isValid) } + fun modifyUserInfo() { + viewModelScope.launch { + myPageRepository.editProfile( + MyPageProfileEdit( + name = _state.value.name, + profileImage = _state.value.profile + ) + ).onSuccess { + _sideEffects.emit(ProfileEditSideEffect.NavigateUp) + }.onFailure { + _sideEffects.emit(ProfileEditSideEffect.ShowToast(R.string.server_failure)) + } + } + } + } \ No newline at end of file diff --git a/feature/src/main/java/com/terning/feature/mypage/profileedit/navigation/ProfileEditNavigation.kt b/feature/src/main/java/com/terning/feature/mypage/profileedit/navigation/ProfileEditNavigation.kt index 71ef7f910..61b250f75 100644 --- a/feature/src/main/java/com/terning/feature/mypage/profileedit/navigation/ProfileEditNavigation.kt +++ b/feature/src/main/java/com/terning/feature/mypage/profileedit/navigation/ProfileEditNavigation.kt @@ -16,11 +16,11 @@ import kotlinx.serialization.Serializable fun NavController.navigateProfileEdit( name: String, - profile: Int, + profileImage: String, navOptions: NavOptions? = null ) { navigate( - route = ProfileEdit(name = name, profile = profile), + route = ProfileEdit(name = name, profileImage = profileImage), navOptions = navOptions ) } @@ -45,7 +45,7 @@ fun NavGraphBuilder.profileEditNavGraph( val args = it.toRoute() ProfileEditRoute( initialName = args.name, - initialProfile = args.profile, + initialProfile = args.profileImage, navigateUp = { navHostController.navigateUp() } ) } @@ -54,5 +54,5 @@ fun NavGraphBuilder.profileEditNavGraph( @Serializable data class ProfileEdit( val name: String, - val profile: Int + val profileImage: String ) : Route \ No newline at end of file diff --git a/feature/src/main/java/com/terning/feature/onboarding/signup/SignUpRoute.kt b/feature/src/main/java/com/terning/feature/onboarding/signup/SignUpRoute.kt index 4be2f12c7..ba7e5c715 100644 --- a/feature/src/main/java/com/terning/feature/onboarding/signup/SignUpRoute.kt +++ b/feature/src/main/java/com/terning/feature/onboarding/signup/SignUpRoute.kt @@ -63,9 +63,9 @@ fun SignUpRoute( if (state.showBottomSheet) { ProfileBottomSheet( onDismiss = { viewModel.updateBottomSheet(false) }, - onSaveClick = { index -> + onSaveClick = { profileImage -> viewModel.updateBottomSheet(false) - viewModel.updateProfileImage(index) + viewModel.updateProfileImage(profileImage.stringValue) }, initialSelectedOption = state.profileImage ) @@ -127,7 +127,7 @@ fun SignUpScreen( modifier = Modifier.noRippleClickable { onProfileEditClick(true) }, - index = state.profileImage + profileImage = state.profileImage ) } Column( @@ -167,7 +167,7 @@ fun SignUpScreenPreview() { onSignUpClick = {}, onInputChange = {}, onProfileEditClick = {}, - onValidationChanged = {} + onValidationChanged = {}, ) } } \ No newline at end of file diff --git a/feature/src/main/java/com/terning/feature/onboarding/signup/SignUpState.kt b/feature/src/main/java/com/terning/feature/onboarding/signup/SignUpState.kt index 5a3f8b253..773904e4c 100644 --- a/feature/src/main/java/com/terning/feature/onboarding/signup/SignUpState.kt +++ b/feature/src/main/java/com/terning/feature/onboarding/signup/SignUpState.kt @@ -2,7 +2,7 @@ package com.terning.feature.onboarding.signup data class SignUpState( val name: String = "", - val profileImage: Int = 0, + val profileImage: String = "basic", val isButtonValid: Boolean = false, val authId: String = "", val showBottomSheet: Boolean = false diff --git a/feature/src/main/java/com/terning/feature/onboarding/signup/SignUpViewModel.kt b/feature/src/main/java/com/terning/feature/onboarding/signup/SignUpViewModel.kt index 504bf3ada..6493c627b 100644 --- a/feature/src/main/java/com/terning/feature/onboarding/signup/SignUpViewModel.kt +++ b/feature/src/main/java/com/terning/feature/onboarding/signup/SignUpViewModel.kt @@ -36,7 +36,7 @@ class SignUpViewModel @Inject constructor( _state.value = _state.value.copy(name = name) } - fun updateProfileImage(profileImage: Int) { + fun updateProfileImage(profileImage: String) { _state.value = _state.value.copy(profileImage = profileImage) } diff --git a/feature/src/main/res/drawable/ic_terning_profile_00.xml b/feature/src/main/res/drawable/ic_terning_profile_00.xml deleted file mode 100644 index 99edfdf96..000000000 --- a/feature/src/main/res/drawable/ic_terning_profile_00.xml +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/feature/src/main/res/drawable/ic_terning_profile_01.xml b/feature/src/main/res/drawable/ic_terning_profile_01.xml deleted file mode 100644 index 0bfcc7b29..000000000 --- a/feature/src/main/res/drawable/ic_terning_profile_01.xml +++ /dev/null @@ -1,80 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/feature/src/main/res/drawable/ic_terning_profile_02.xml b/feature/src/main/res/drawable/ic_terning_profile_02.xml deleted file mode 100644 index 8ba5ffc15..000000000 --- a/feature/src/main/res/drawable/ic_terning_profile_02.xml +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/feature/src/main/res/drawable/ic_terning_profile_03.xml b/feature/src/main/res/drawable/ic_terning_profile_03.xml deleted file mode 100644 index 25e878efb..000000000 --- a/feature/src/main/res/drawable/ic_terning_profile_03.xml +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/feature/src/main/res/drawable/ic_terning_profile_04.xml b/feature/src/main/res/drawable/ic_terning_profile_04.xml deleted file mode 100644 index 8b27c5c6c..000000000 --- a/feature/src/main/res/drawable/ic_terning_profile_04.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/feature/src/main/res/drawable/ic_terning_profile_05.xml b/feature/src/main/res/drawable/ic_terning_profile_05.xml deleted file mode 100644 index 9a32c789e..000000000 --- a/feature/src/main/res/drawable/ic_terning_profile_05.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - - - - - - - - - - -