From 01637536ab58db340c1ced30cb52bebc6261983e Mon Sep 17 00:00:00 2001 From: ImHyungsuk Date: Sat, 11 Oct 2025 01:53:55 +0900 Subject: [PATCH 01/10] =?UTF-8?q?feature#149=20=ED=9A=8C=EC=9B=90=ED=83=88?= =?UTF-8?q?=ED=87=B4=20ui=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../component/button/SolplyButton.kt | 1 - .../datasource/MypageRemoteDataSource.kt | 2 + .../response/GetWithdrawListResponseDto.kt | 20 ++ .../mypage/repository/MypageRepositoryImpl.kt | 12 ++ domain/mypage/build.gradle.kts | 2 + .../solply/mypage/model/WithdrawEntity.kt | 6 + .../solply/mypage/model/WithdrawType.kt | 15 ++ .../mypage/repository/MypageRepository.kt | 2 + .../teamsolply/solply/mypage/MypageScreen.kt | 2 +- .../mypage/withdraw/WithdrawContract.kt | 24 +++ .../solply/mypage/withdraw/WithdrawScreen.kt | 202 ++++++++++++++++++ .../mypage/withdraw/WithdrawViewModel.kt | 36 ++++ .../withdraw/navigation/WithdrawNavigation.kt | 36 ++++ .../mypage/src/main/res/values/strings.xml | 6 +- .../datasource/MypageRemoteDataSourceImpl.kt | 4 + .../solply/mypage/service/MypageService.kt | 4 + 16 files changed, 371 insertions(+), 3 deletions(-) create mode 100644 data/mypage/src/main/java/com/teamsolply/solply/mypage/dto/response/GetWithdrawListResponseDto.kt create mode 100644 domain/mypage/src/main/java/com/teamsolply/solply/mypage/model/WithdrawEntity.kt create mode 100644 domain/mypage/src/main/java/com/teamsolply/solply/mypage/model/WithdrawType.kt create mode 100644 feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawContract.kt create mode 100644 feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawScreen.kt create mode 100644 feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawViewModel.kt create mode 100644 feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/navigation/WithdrawNavigation.kt diff --git a/core/designsystem/src/main/java/com/teamsolply/solply/designsystem/component/button/SolplyButton.kt b/core/designsystem/src/main/java/com/teamsolply/solply/designsystem/component/button/SolplyButton.kt index 1e0a9bac..0825a733 100644 --- a/core/designsystem/src/main/java/com/teamsolply/solply/designsystem/component/button/SolplyButton.kt +++ b/core/designsystem/src/main/java/com/teamsolply/solply/designsystem/component/button/SolplyButton.kt @@ -6,7 +6,6 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.CircleShape import androidx.compose.material3.Icon import androidx.compose.material3.Text diff --git a/data/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageRemoteDataSource.kt b/data/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageRemoteDataSource.kt index 3d18a557..fa36d702 100644 --- a/data/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageRemoteDataSource.kt +++ b/data/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageRemoteDataSource.kt @@ -2,6 +2,7 @@ package com.teamsolply.solply.mypage.datasource import com.teamsolply.solply.mypage.dto.response.GetPersonaListResponseDto import com.teamsolply.solply.mypage.dto.response.GetUserInfoResponseDto +import com.teamsolply.solply.mypage.dto.response.GetWithdrawListResponseDto import com.teamsolply.solply.mypage.dto.response.NicknameDuplicateResponseDto import com.teamsolply.solply.mypage.dto.response.PlaceListResponseDto @@ -10,4 +11,5 @@ interface MypageRemoteDataSource { suspend fun getPlaceList(townId: Long): PlaceListResponseDto suspend fun getPersonaList(): GetPersonaListResponseDto suspend fun checkNicknameDuplicate(nickname: String): NicknameDuplicateResponseDto + suspend fun getWithdrawList(): GetWithdrawListResponseDto } diff --git a/data/mypage/src/main/java/com/teamsolply/solply/mypage/dto/response/GetWithdrawListResponseDto.kt b/data/mypage/src/main/java/com/teamsolply/solply/mypage/dto/response/GetWithdrawListResponseDto.kt new file mode 100644 index 00000000..2e7540be --- /dev/null +++ b/data/mypage/src/main/java/com/teamsolply/solply/mypage/dto/response/GetWithdrawListResponseDto.kt @@ -0,0 +1,20 @@ +package com.teamsolply.solply.mypage.dto.response + +import com.teamsolply.solply.mypage.model.WithdrawType +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class GetWithdrawListResponseDto( + @SerialName("description") + val withdrawList: List +) + +@Serializable +data class WithdrawResponseDto( + @SerialName("withdrawType") + val withdrawType: WithdrawType, + + @SerialName("description") + val description: String +) \ No newline at end of file diff --git a/data/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepositoryImpl.kt b/data/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepositoryImpl.kt index b828e137..616285fd 100644 --- a/data/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepositoryImpl.kt +++ b/data/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepositoryImpl.kt @@ -6,6 +6,7 @@ import com.teamsolply.solply.mypage.dto.response.toDomain import com.teamsolply.solply.mypage.model.PersonaEntity import com.teamsolply.solply.mypage.model.PlaceInfoEntity import com.teamsolply.solply.mypage.model.UserInfo +import com.teamsolply.solply.mypage.model.WithdrawEntity import javax.inject.Inject class MypageRepositoryImpl @Inject constructor( @@ -46,4 +47,15 @@ class MypageRepositoryImpl @Inject constructor( override suspend fun checkNicknameDuplicate(nickname: String): Result = runCatching { mypageRemoteDataSource.checkNicknameDuplicate(nickname = nickname).isDuplicated } + + override suspend fun getWithdrawList(): Result> = runCatching { + mypageRemoteDataSource.getWithdrawList().withdrawList + }.mapCatching { list -> + list.map { reason -> + WithdrawEntity( + withdrawType = reason.withdrawType, + description = reason.description + ) + } + } } diff --git a/domain/mypage/build.gradle.kts b/domain/mypage/build.gradle.kts index 7f643ef7..82bd86b1 100644 --- a/domain/mypage/build.gradle.kts +++ b/domain/mypage/build.gradle.kts @@ -1,8 +1,10 @@ plugins { alias(libs.plugins.solply.java.library) + alias(libs.plugins.kotlin.serialization) } dependencies { implementation(projects.core.model) implementation(libs.bundles.coroutine) + implementation(libs.kotlinx.serialization.json) } diff --git a/domain/mypage/src/main/java/com/teamsolply/solply/mypage/model/WithdrawEntity.kt b/domain/mypage/src/main/java/com/teamsolply/solply/mypage/model/WithdrawEntity.kt new file mode 100644 index 00000000..4358a847 --- /dev/null +++ b/domain/mypage/src/main/java/com/teamsolply/solply/mypage/model/WithdrawEntity.kt @@ -0,0 +1,6 @@ +package com.teamsolply.solply.mypage.model + +data class WithdrawEntity( + val withdrawType: WithdrawType, + val description: String +) diff --git a/domain/mypage/src/main/java/com/teamsolply/solply/mypage/model/WithdrawType.kt b/domain/mypage/src/main/java/com/teamsolply/solply/mypage/model/WithdrawType.kt new file mode 100644 index 00000000..be6c6122 --- /dev/null +++ b/domain/mypage/src/main/java/com/teamsolply/solply/mypage/model/WithdrawType.kt @@ -0,0 +1,15 @@ +package com.teamsolply.solply.mypage.model + +import kotlinx.serialization.Serializable + +@Serializable +enum class WithdrawType( + val description: String +) { + NOT_USE("자주 사용하지 않아서"), + DEFICIENT_INFO("원하는 지역과 장소가 부족해서"), + INCONVENIENT("앱 기능이 불편해서"), + HATE_RECOMMEND("추천 콘텐츠가 나와 맞지 않아서"), + USE_OTHER_SERVICE("다른 서비스를 사용하고 있습니다."), + OTHERS("기타") +} \ No newline at end of file diff --git a/domain/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepository.kt b/domain/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepository.kt index 86b7648a..13bb0ab0 100644 --- a/domain/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepository.kt +++ b/domain/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepository.kt @@ -3,10 +3,12 @@ package com.teamsolply.solply.mypage.repository import com.teamsolply.solply.mypage.model.PersonaEntity import com.teamsolply.solply.mypage.model.PlaceInfoEntity import com.teamsolply.solply.mypage.model.UserInfo +import com.teamsolply.solply.mypage.model.WithdrawEntity interface MypageRepository { suspend fun getUserInfo(): Result suspend fun getPlaceList(townId: Long): Result> suspend fun getPersonaList(): Result> suspend fun checkNicknameDuplicate(nickname: String): Result + suspend fun getWithdrawList(): Result> } diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageScreen.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageScreen.kt index c6cbd419..4ab28c59 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageScreen.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageScreen.kt @@ -91,7 +91,7 @@ fun MypageScreen( SolplyConfirmDialog( text = stringResource(R.string.logout_dialog), confirmButtonText = stringResource(R.string.logout_dialog_confirm), - dismissButtonText = stringResource(R.string.mypage_dialog_cancel), + dismissButtonText = stringResource(R.string.dialog_cancel), onClickConfirm = onDialogConfirmClick, onClickDismiss = onDialogDismissClick ) diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawContract.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawContract.kt new file mode 100644 index 00000000..35370258 --- /dev/null +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawContract.kt @@ -0,0 +1,24 @@ +package com.teamsolply.solply.mypage.withdraw + +import com.teamsolply.solply.mypage.model.WithdrawEntity +import com.teamsolply.solply.ui.base.SideEffect +import com.teamsolply.solply.ui.base.UiIntent +import com.teamsolply.solply.ui.base.UiState + +data class WithdrawState( + val withdrawList: List = emptyList(), + val dialogState: Boolean = false, + val buttonEnabled: Boolean = false +) : UiState + +sealed interface WithdrawIntent : UiIntent { + data object Init : WithdrawIntent + + data object DialogConfirmClick : WithdrawIntent + data object DialogDismissClick : WithdrawIntent +} + +sealed interface WithdrawSideEffect : SideEffect { + data object NavigateToBack : WithdrawSideEffect + data object NavigateToProfile : WithdrawSideEffect +} diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawScreen.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawScreen.kt new file mode 100644 index 00000000..613a5f89 --- /dev/null +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawScreen.kt @@ -0,0 +1,202 @@ +package com.teamsolply.solply.mypage.withdraw + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.itemsIndexed +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.hilt.navigation.compose.hiltViewModel +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.teamsolply.solply.designsystem.component.button.SolplyBasicButton +import com.teamsolply.solply.designsystem.component.dialog.SolplyConfirmDialog +import com.teamsolply.solply.designsystem.component.textfield.SolplyFixedReportTextField +import com.teamsolply.solply.designsystem.component.topbar.SolplyTopBar +import com.teamsolply.solply.designsystem.theme.SolplyTheme +import com.teamsolply.solply.mypage.R +import com.teamsolply.solply.mypage.model.WithdrawEntity +import com.teamsolply.solply.mypage.model.WithdrawType +import com.teamsolply.solply.ui.extension.customClickable +import com.teamsolply.solply.ui.lifecycle.LaunchedEffectWithLifecycle +import kotlinx.coroutines.flow.collectLatest + +@Composable +fun WithdrawRoute( + paddingValues: PaddingValues, + navigateToBack: () -> Unit, + navigateToProfile: () -> Unit, + viewModel: WithdrawViewModel = hiltViewModel() +) { + val uiState by viewModel.uiState.collectAsStateWithLifecycle() + + LaunchedEffect(Unit) { + viewModel.sendIntent(WithdrawIntent.Init) + } + + LaunchedEffectWithLifecycle { + viewModel.sideEffect.collectLatest { sideEffect -> + when (sideEffect) { + WithdrawSideEffect.NavigateToBack -> navigateToBack() + WithdrawSideEffect.NavigateToProfile -> navigateToProfile() + } + } + } + + WithdrawScreen( + withdrawList = emptyList(), + selectedIndex = -1, + buttonEnabled = uiState.buttonEnabled, + dialogState = uiState.dialogState, + onWithdrawItemClick = {}, + onTextFieldValueChange = {}, + onDialogConfirmClick = {}, + onDialogDismissClick = {}, + modifier = Modifier.padding(paddingValues) + ) +} + +@Composable +fun WithdrawScreen( + withdrawList: List, + selectedIndex: Int, + buttonEnabled: Boolean, + dialogState: Boolean, + onWithdrawItemClick: (Int) -> Unit, + onTextFieldValueChange: (String) -> Unit, + onDialogConfirmClick: () -> Unit, + onDialogDismissClick: () -> Unit, + modifier: Modifier = Modifier +) { + if (dialogState) { + SolplyConfirmDialog( + text = stringResource(R.string.mypage_withdraw), + confirmButtonText = stringResource(R.string.withdraw_dialog_confirm), + dismissButtonText = stringResource(R.string.dialog_cancel), + onClickConfirm = onDialogConfirmClick, + onClickDismiss = onDialogDismissClick + ) + } + Column( + modifier = modifier + .fillMaxSize() + .background(SolplyTheme.colors.white), + verticalArrangement = Arrangement.SpaceBetween, + horizontalAlignment = Alignment.CenterHorizontally + ) { + LazyColumn { + item { + SolplyTopBar( + barText = stringResource(R.string.mypage_withdraw), + onBackButtonClick = {} + ) + } + itemsIndexed(withdrawList) { index, item -> + Column( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 20.dp) + .customClickable( + rippleEnabled = false, + onClick = { onWithdrawItemClick(index) } + ), + verticalArrangement = Arrangement.Top, + horizontalAlignment = Alignment.Start + ) { + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween + ) { + Text( + text = item.description, + style = if (index == selectedIndex) SolplyTheme.typography.body16M else SolplyTheme.typography.body16R, + color = SolplyTheme.colors.black, + modifier = Modifier.padding(vertical = 11.dp) + ) + if (index == selectedIndex) { + Icon( + painter = painterResource(com.teamsolply.solply.designsystem.R.drawable.ic_filter_selected), + contentDescription = "", + tint = Color.Unspecified + ) + } + } + if (index == withdrawList.lastIndex && selectedIndex == withdrawList.lastIndex) { + SolplyFixedReportTextField( + value = "", + onValueChange = { onTextFieldValueChange(it) }, + ) + } else { + HorizontalDivider( + thickness = 1.dp, + color = SolplyTheme.colors.gray200 + ) + } + } + } + } + SolplyBasicButton( + text = stringResource(R.string.mypage_withdraw), + onClick = {}, + enabledBackgroundColor = if (buttonEnabled) { + SolplyTheme.colors.gray900 + } else { + SolplyTheme.colors.gray300 + }, + textColor = if (buttonEnabled) { + SolplyTheme.colors.white + } else { + SolplyTheme.colors.gray800 + }, + modifier = Modifier.padding(bottom = 24.dp, start = 20.dp, end = 20.dp) + ) + } +} + +@Preview +@Composable +private fun WithdrawScreenPreview() { + SolplyTheme { + WithdrawScreen( + withdrawList = listOf( + WithdrawEntity( + withdrawType = WithdrawType.NOT_USE, + description = "자주 사용하지 않아서" + ), + WithdrawEntity( + withdrawType = WithdrawType.NOT_USE, + description = "원하는 지역과 장소가 부족해서" + ), + WithdrawEntity( + withdrawType = WithdrawType.OTHERS, + description = "기타 (직접 입력)" + ) + ), + selectedIndex = 2, + buttonEnabled = false, + dialogState = false, + onWithdrawItemClick = {}, + onDialogConfirmClick = {}, + onTextFieldValueChange = {}, + onDialogDismissClick = {}, + modifier = Modifier.fillMaxSize() + ) + } +} \ No newline at end of file diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawViewModel.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawViewModel.kt new file mode 100644 index 00000000..603e3f30 --- /dev/null +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawViewModel.kt @@ -0,0 +1,36 @@ +package com.teamsolply.solply.mypage.withdraw + +import androidx.lifecycle.viewModelScope +import com.teamsolply.solply.mypage.repository.MypageRepository +import com.teamsolply.solply.ui.base.BaseViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class WithdrawViewModel @Inject constructor( + private val mypageRepository: MypageRepository +) : + BaseViewModel(WithdrawState()) { + override fun handleIntent(intent: WithdrawIntent) { + when (intent) { + WithdrawIntent.Init -> { + getWithdrawList() + } + + WithdrawIntent.DialogConfirmClick -> TODO() + WithdrawIntent.DialogDismissClick -> TODO() + } + } + + private fun getWithdrawList() { + viewModelScope.launch { + mypageRepository.getWithdrawList().onSuccess { + reduce { + copy(withdrawList = it) + } + } + } + } + +} \ No newline at end of file diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/navigation/WithdrawNavigation.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/navigation/WithdrawNavigation.kt new file mode 100644 index 00000000..7a40e717 --- /dev/null +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/navigation/WithdrawNavigation.kt @@ -0,0 +1,36 @@ +package com.teamsolply.solply.mypage.withdraw.navigation + +import androidx.compose.foundation.layout.PaddingValues +import androidx.hilt.navigation.compose.hiltViewModel +import androidx.navigation.NavController +import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavOptions +import androidx.navigation.compose.composable +import com.teamsolply.solply.mypage.withdraw.WithdrawRoute +import com.teamsolply.solply.mypage.withdraw.WithdrawViewModel +import com.teamsolply.solply.navigation.Route +import kotlinx.serialization.Serializable + +fun NavController.navigateWithdraw( + navOptions: NavOptions +) { + navigate(Withdraw, navOptions) +} + +fun NavGraphBuilder.withdrawNavGraph( + paddingValues: PaddingValues +) { + composable { backStackEntry -> + val viewModel: WithdrawViewModel = hiltViewModel(backStackEntry) + WithdrawRoute( + paddingValues = paddingValues, + navigateToBack = {}, + navigateToProfile = {}, + viewModel = viewModel + ) + } + +} + +@Serializable +data object Withdraw : Route \ No newline at end of file diff --git a/feature/mypage/src/main/res/values/strings.xml b/feature/mypage/src/main/res/values/strings.xml index 7725f99c..35ccc510 100644 --- a/feature/mypage/src/main/res/values/strings.xml +++ b/feature/mypage/src/main/res/values/strings.xml @@ -3,6 +3,7 @@ 계정 설정 고객센터 로그아웃 + 탈퇴하기 프로필 수정 기본 프로필 @@ -15,6 +16,9 @@ 취소 로그아웃하시겠습니까? - 취소 + 취소 로그아웃 + + 탈퇴 + \ No newline at end of file diff --git a/remote/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageRemoteDataSourceImpl.kt b/remote/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageRemoteDataSourceImpl.kt index 7cec758e..ce99f5a6 100644 --- a/remote/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageRemoteDataSourceImpl.kt +++ b/remote/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageRemoteDataSourceImpl.kt @@ -3,6 +3,7 @@ package com.teamsolply.solply.mypage.datasource import android.util.Log import com.teamsolply.solply.mypage.dto.response.GetPersonaListResponseDto import com.teamsolply.solply.mypage.dto.response.GetUserInfoResponseDto +import com.teamsolply.solply.mypage.dto.response.GetWithdrawListResponseDto import com.teamsolply.solply.mypage.dto.response.NicknameDuplicateResponseDto import com.teamsolply.solply.mypage.service.MypageService import javax.inject.Inject @@ -24,4 +25,7 @@ class MypageRemoteDataSourceImpl @Inject constructor( override suspend fun checkNicknameDuplicate(nickname: String): NicknameDuplicateResponseDto = mypageService.checkNicknameDuplicate(nickname = nickname).data + + override suspend fun getWithdrawList(): GetWithdrawListResponseDto = + mypageService.getWithdrawList().data } diff --git a/remote/mypage/src/main/java/com/teamsolply/solply/mypage/service/MypageService.kt b/remote/mypage/src/main/java/com/teamsolply/solply/mypage/service/MypageService.kt index ce98be63..8ef33d8f 100644 --- a/remote/mypage/src/main/java/com/teamsolply/solply/mypage/service/MypageService.kt +++ b/remote/mypage/src/main/java/com/teamsolply/solply/mypage/service/MypageService.kt @@ -2,6 +2,7 @@ package com.teamsolply.solply.mypage.service import com.teamsolply.solply.mypage.dto.response.GetPersonaListResponseDto import com.teamsolply.solply.mypage.dto.response.GetUserInfoResponseDto +import com.teamsolply.solply.mypage.dto.response.GetWithdrawListResponseDto import com.teamsolply.solply.mypage.dto.response.NicknameDuplicateResponseDto import com.teamsolply.solply.mypage.dto.response.PlaceListResponseDto import com.teamsolply.solply.network.model.BaseResponse @@ -25,4 +26,7 @@ interface MypageService { suspend fun checkNicknameDuplicate( @Query("nickname") nickname: String ): BaseResponse + + @GET("api/users/withdraw/reasons") + suspend fun getWithdrawList(): BaseResponse } From 46ad315081fff5af69506ec4a054928daccc8127 Mon Sep 17 00:00:00 2001 From: ImHyungsuk Date: Sat, 11 Oct 2025 02:43:27 +0900 Subject: [PATCH 02/10] =?UTF-8?q?feature#149=20=ED=9A=8C=EC=9B=90=ED=83=88?= =?UTF-8?q?=ED=87=B4=20=EC=83=81=ED=83=9C=EA=B4=80=EB=A6=AC=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../datasource/MypageRemoteDataSource.kt | 2 + .../mypage/repository/MypageRepositoryImpl.kt | 6 ++- .../mypage/repository/MypageRepository.kt | 1 + .../teamsolply/solply/main/MainNavigator.kt | 7 ++++ .../com/teamsolply/solply/main/MainScreen.kt | 9 +++++ .../solply/mypage/MypageContract.kt | 3 +- .../teamsolply/solply/mypage/MypageScreen.kt | 9 ++++- .../solply/mypage/MypageViewModel.kt | 13 +++++-- .../mypage/navigation/MypageNavigation.kt | 2 + .../mypage/withdraw/WithdrawContract.kt | 8 +++- .../solply/mypage/withdraw/WithdrawScreen.kt | 26 +++++++++---- .../mypage/withdraw/WithdrawViewModel.kt | 39 ++++++++++++++++++- .../withdraw/navigation/WithdrawNavigation.kt | 3 +- .../mypage/src/main/res/values/strings.xml | 1 + .../datasource/MypageRemoteDataSourceImpl.kt | 4 +- .../solply/mypage/service/MypageService.kt | 5 +++ 16 files changed, 117 insertions(+), 21 deletions(-) diff --git a/data/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageRemoteDataSource.kt b/data/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageRemoteDataSource.kt index fa36d702..4c3bd3e8 100644 --- a/data/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageRemoteDataSource.kt +++ b/data/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageRemoteDataSource.kt @@ -5,6 +5,7 @@ import com.teamsolply.solply.mypage.dto.response.GetUserInfoResponseDto import com.teamsolply.solply.mypage.dto.response.GetWithdrawListResponseDto import com.teamsolply.solply.mypage.dto.response.NicknameDuplicateResponseDto import com.teamsolply.solply.mypage.dto.response.PlaceListResponseDto +import com.teamsolply.solply.network.model.NullableBaseResponse interface MypageRemoteDataSource { suspend fun getUserInfo(): GetUserInfoResponseDto @@ -12,4 +13,5 @@ interface MypageRemoteDataSource { suspend fun getPersonaList(): GetPersonaListResponseDto suspend fun checkNicknameDuplicate(nickname: String): NicknameDuplicateResponseDto suspend fun getWithdrawList(): GetWithdrawListResponseDto + suspend fun deleteUser(): NullableBaseResponse } diff --git a/data/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepositoryImpl.kt b/data/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepositoryImpl.kt index 616285fd..8c268e25 100644 --- a/data/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepositoryImpl.kt +++ b/data/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepositoryImpl.kt @@ -1,6 +1,5 @@ package com.teamsolply.solply.mypage.repository -import android.util.Log import com.teamsolply.solply.mypage.datasource.MypageRemoteDataSource import com.teamsolply.solply.mypage.dto.response.toDomain import com.teamsolply.solply.mypage.model.PersonaEntity @@ -35,7 +34,6 @@ class MypageRepositoryImpl @Inject constructor( override suspend fun getPersonaList(): Result> = runCatching { mypageRemoteDataSource.getPersonaList().personaDtoList }.mapCatching { personaList -> - Log.d("persona: ", "repo impl start") personaList.map { persona -> PersonaEntity( personaType = persona.personaType, @@ -58,4 +56,8 @@ class MypageRepositoryImpl @Inject constructor( ) } } + + override suspend fun deleteUser(): Result = + runCatching { mypageRemoteDataSource.deleteUser() } + } diff --git a/domain/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepository.kt b/domain/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepository.kt index 13bb0ab0..56ec579d 100644 --- a/domain/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepository.kt +++ b/domain/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepository.kt @@ -11,4 +11,5 @@ interface MypageRepository { suspend fun getPersonaList(): Result> suspend fun checkNicknameDuplicate(nickname: String): Result suspend fun getWithdrawList(): Result> + suspend fun deleteUser(): Result } diff --git a/feature/main/src/main/java/com/teamsolply/solply/main/MainNavigator.kt b/feature/main/src/main/java/com/teamsolply/solply/main/MainNavigator.kt index 33085e7f..a739dff2 100644 --- a/feature/main/src/main/java/com/teamsolply/solply/main/MainNavigator.kt +++ b/feature/main/src/main/java/com/teamsolply/solply/main/MainNavigator.kt @@ -18,6 +18,7 @@ import com.teamsolply.solply.main.splash.Splash import com.teamsolply.solply.maps.navigation.navigateMaps import com.teamsolply.solply.mypage.navigation.navigateMypage import com.teamsolply.solply.mypage.profile.navigation.navigateProfile +import com.teamsolply.solply.mypage.withdraw.navigation.navigateWithdraw import com.teamsolply.solply.oauth.navigation.navigateOauth import com.teamsolply.solply.onboarding.navigation.navigateOnBoarding import com.teamsolply.solply.place.navigation.navigatePlace @@ -154,6 +155,12 @@ internal class MainNavigator( ) } + fun navigateToWithdraw( + navOptions: NavOptions + ) { + navController.navigateWithdraw(navOptions) + } + fun navigateToFavoriteTown(navOptions: NavOptions = navOptions {}) { navController.navigateFavoriteTown(navOptions) } diff --git a/feature/main/src/main/java/com/teamsolply/solply/main/MainScreen.kt b/feature/main/src/main/java/com/teamsolply/solply/main/MainScreen.kt index 3c1522d7..78c25c79 100644 --- a/feature/main/src/main/java/com/teamsolply/solply/main/MainScreen.kt +++ b/feature/main/src/main/java/com/teamsolply/solply/main/MainScreen.kt @@ -42,6 +42,7 @@ import com.teamsolply.solply.model.SnackBarType import com.teamsolply.solply.mypage.navigation.Mypage import com.teamsolply.solply.mypage.navigation.mypageNavGraph import com.teamsolply.solply.mypage.profile.navigation.profileNavGraph +import com.teamsolply.solply.mypage.withdraw.navigation.withdrawNavGraph import com.teamsolply.solply.oauth.navigation.oauthNavGraph import com.teamsolply.solply.onboarding.navigation.onBoardingNavGraph import com.teamsolply.solply.place.navigation.placeNavGraph @@ -339,6 +340,10 @@ internal fun MainScreen( navigateToProfile = { val navOptions = navOptions { } navigator.navigateToProfile(navOptions) + }, + navigateToWithdraw = { + val navOptions = navOptions { } + navigator.navigateToWithdraw(navOptions) } ) profileNavGraph( @@ -352,6 +357,10 @@ internal fun MainScreen( navigator.navigateToMypage(navOptions = navOptions) } ) + withdrawNavGraph( + paddingValues = innerPadding, + navigateToBack = navigator::navigateToBack + ) favoriteTownNavGraph( paddingValues = innerPadding, navigateToBack = navigator::navigateToBack diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageContract.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageContract.kt index bdeca22e..1504a26a 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageContract.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageContract.kt @@ -24,15 +24,16 @@ sealed interface MypageIntent : UiIntent { data object Init : MypageIntent data object LogOutButtonClick : MypageIntent - data object WithdrawButtonClick : MypageIntent data object DialogConfirmClick : MypageIntent data object DialogDismissClick : MypageIntent data object ProfileEditClick : MypageIntent + data object WithdrawClick : MypageIntent } sealed interface MypageSideEffect : SideEffect { data object NavigateToBack : MypageSideEffect data object NavigateToProfile : MypageSideEffect + data object NavigateToWithdraw : MypageSideEffect } diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageScreen.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageScreen.kt index 4ab28c59..2a348f0a 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageScreen.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageScreen.kt @@ -45,6 +45,7 @@ fun MypageRoute( paddingValues: PaddingValues, navigateToBack: () -> Unit, navigateToProfile: () -> Unit, + navigateToWithdraw: () -> Unit, viewModel: MypageViewModel = hiltViewModel() ) { val uiState by viewModel.uiState.collectAsStateWithLifecycle() @@ -58,6 +59,7 @@ fun MypageRoute( when (sideEffect) { MypageSideEffect.NavigateToBack -> navigateToBack() MypageSideEffect.NavigateToProfile -> navigateToProfile() + MypageSideEffect.NavigateToWithdraw -> navigateToWithdraw() } } } @@ -69,6 +71,7 @@ fun MypageRoute( onBackButtonClick = navigateToBack, onProfileEditClick = { viewModel.sendIntent(MypageIntent.ProfileEditClick) }, onLogOutClick = { viewModel.sendIntent(MypageIntent.LogOutButtonClick) }, + onWithdrawClick = { viewModel.sendIntent(MypageIntent.WithdrawClick) }, onDialogConfirmClick = { viewModel.sendIntent(MypageIntent.DialogConfirmClick) }, onDialogDismissClick = { viewModel.sendIntent(MypageIntent.DialogDismissClick) }, modifier = Modifier.padding(paddingValues) @@ -83,6 +86,7 @@ fun MypageScreen( onBackButtonClick: () -> Unit, onProfileEditClick: () -> Unit, onLogOutClick: () -> Unit, + onWithdrawClick: () -> Unit, onDialogConfirmClick: () -> Unit, onDialogDismissClick: () -> Unit, modifier: Modifier = Modifier @@ -235,8 +239,8 @@ fun MypageScreen( isBorderEnabled = true ) MypageSettingItem( - text = "탈퇴하기", - onClick = { /* TODO */ }, + text = stringResource(R.string.mypage_withdraw), + onClick = onWithdrawClick, isBorderEnabled = false ) Spacer(modifier = Modifier.height(8.dp)) @@ -255,6 +259,7 @@ private fun MypageScreenPreview() { onBackButtonClick = {}, onProfileEditClick = {}, onLogOutClick = {}, + onWithdrawClick = {}, onDialogConfirmClick = {}, onDialogDismissClick = {} ) diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageViewModel.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageViewModel.kt index 024b3409..bd9e411a 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageViewModel.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageViewModel.kt @@ -25,11 +25,8 @@ class MypageViewModel @Inject constructor( } } - MypageIntent.WithdrawButtonClick -> { - } - MypageIntent.DialogConfirmClick -> { - // TODO 로그아웃 api + fetchLogout() reduce { copy(dialogState = false) } @@ -44,6 +41,10 @@ class MypageViewModel @Inject constructor( MypageIntent.ProfileEditClick -> { postSideEffect(MypageSideEffect.NavigateToProfile) } + + MypageIntent.WithdrawClick -> { + postSideEffect(MypageSideEffect.NavigateToWithdraw) + } } } @@ -71,4 +72,8 @@ class MypageViewModel @Inject constructor( } } } + + private fun fetchLogout() { + // TODO 로그아웃 api + } } diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/navigation/MypageNavigation.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/navigation/MypageNavigation.kt index b272060d..b16028d9 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/navigation/MypageNavigation.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/navigation/MypageNavigation.kt @@ -20,6 +20,7 @@ fun NavController.navigateMypage( fun NavGraphBuilder.mypageNavGraph( navigateToBack: () -> Unit, navigateToProfile: () -> Unit, + navigateToWithdraw: () -> Unit, paddingValues: PaddingValues ) { composable { backStackEntry -> @@ -28,6 +29,7 @@ fun NavGraphBuilder.mypageNavGraph( paddingValues = paddingValues, navigateToBack = navigateToBack, navigateToProfile = navigateToProfile, + navigateToWithdraw = navigateToWithdraw, viewModel = viewModel ) } diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawContract.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawContract.kt index 35370258..06540da0 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawContract.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawContract.kt @@ -7,13 +7,19 @@ import com.teamsolply.solply.ui.base.UiState data class WithdrawState( val withdrawList: List = emptyList(), + val selectedIndex: Int = -1, + val withdrawReason: String = "", + val buttonEnabled: Boolean = false, val dialogState: Boolean = false, - val buttonEnabled: Boolean = false ) : UiState sealed interface WithdrawIntent : UiIntent { data object Init : WithdrawIntent + data class WithdrawItemClick(val index: Int) : WithdrawIntent + data object WithdrawButtonClick : WithdrawIntent + data class WithdrawReasonInput(val reason: String) : WithdrawIntent + data object DialogConfirmClick : WithdrawIntent data object DialogDismissClick : WithdrawIntent } diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawScreen.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawScreen.kt index 613a5f89..56112ca0 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawScreen.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawScreen.kt @@ -60,14 +60,16 @@ fun WithdrawRoute( } WithdrawScreen( - withdrawList = emptyList(), - selectedIndex = -1, + withdrawList = uiState.withdrawList, + withdrawReason = uiState.withdrawReason, + selectedIndex = uiState.selectedIndex, buttonEnabled = uiState.buttonEnabled, dialogState = uiState.dialogState, - onWithdrawItemClick = {}, - onTextFieldValueChange = {}, - onDialogConfirmClick = {}, - onDialogDismissClick = {}, + onWithdrawItemClick = { viewModel.sendIntent(WithdrawIntent.WithdrawItemClick(it)) }, + onTextFieldValueChange = { viewModel.sendIntent(WithdrawIntent.WithdrawReasonInput(it)) }, + onWithdrawButtonClick = { viewModel.sendIntent(WithdrawIntent.WithdrawButtonClick) }, + onDialogConfirmClick = { viewModel.sendIntent(WithdrawIntent.DialogConfirmClick) }, + onDialogDismissClick = { viewModel.sendIntent(WithdrawIntent.DialogDismissClick) }, modifier = Modifier.padding(paddingValues) ) } @@ -75,11 +77,13 @@ fun WithdrawRoute( @Composable fun WithdrawScreen( withdrawList: List, + withdrawReason: String, selectedIndex: Int, buttonEnabled: Boolean, dialogState: Boolean, onWithdrawItemClick: (Int) -> Unit, onTextFieldValueChange: (String) -> Unit, + onWithdrawButtonClick: () -> Unit, onDialogConfirmClick: () -> Unit, onDialogDismissClick: () -> Unit, modifier: Modifier = Modifier @@ -140,7 +144,7 @@ fun WithdrawScreen( } if (index == withdrawList.lastIndex && selectedIndex == withdrawList.lastIndex) { SolplyFixedReportTextField( - value = "", + value = withdrawReason, onValueChange = { onTextFieldValueChange(it) }, ) } else { @@ -154,7 +158,11 @@ fun WithdrawScreen( } SolplyBasicButton( text = stringResource(R.string.mypage_withdraw), - onClick = {}, + onClick = { + if (buttonEnabled) { + onWithdrawButtonClick() + } + }, enabledBackgroundColor = if (buttonEnabled) { SolplyTheme.colors.gray900 } else { @@ -189,10 +197,12 @@ private fun WithdrawScreenPreview() { description = "기타 (직접 입력)" ) ), + withdrawReason = "", selectedIndex = 2, buttonEnabled = false, dialogState = false, onWithdrawItemClick = {}, + onWithdrawButtonClick = {}, onDialogConfirmClick = {}, onTextFieldValueChange = {}, onDialogDismissClick = {}, diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawViewModel.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawViewModel.kt index 603e3f30..b11a4a94 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawViewModel.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawViewModel.kt @@ -18,8 +18,38 @@ class WithdrawViewModel @Inject constructor( getWithdrawList() } + is WithdrawIntent.WithdrawReasonInput -> { + reduce { + copy( + withdrawReason = intent.reason, + buttonEnabled = intent.reason.isNotEmpty() + ) + } + } + + is WithdrawIntent.WithdrawItemClick -> { + reduce { + copy( + selectedIndex = intent.index, + buttonEnabled = intent.index != withdrawList.lastIndex + ) + } + } + + WithdrawIntent.WithdrawButtonClick -> { + reduce { + copy( + dialogState = true + ) + } + } + WithdrawIntent.DialogConfirmClick -> TODO() - WithdrawIntent.DialogDismissClick -> TODO() + WithdrawIntent.DialogDismissClick -> { + reduce { + copy(dialogState = false) + } + } } } @@ -33,4 +63,11 @@ class WithdrawViewModel @Inject constructor( } } + private fun fetchWithdraw() { + viewModelScope.launch { + mypageRepository.deleteUser().onSuccess { + // TODO + } + } + } } \ No newline at end of file diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/navigation/WithdrawNavigation.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/navigation/WithdrawNavigation.kt index 7a40e717..98aff51d 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/navigation/WithdrawNavigation.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/navigation/WithdrawNavigation.kt @@ -18,13 +18,14 @@ fun NavController.navigateWithdraw( } fun NavGraphBuilder.withdrawNavGraph( + navigateToBack: () -> Unit, paddingValues: PaddingValues ) { composable { backStackEntry -> val viewModel: WithdrawViewModel = hiltViewModel(backStackEntry) WithdrawRoute( paddingValues = paddingValues, - navigateToBack = {}, + navigateToBack = navigateToBack, navigateToProfile = {}, viewModel = viewModel ) diff --git a/feature/mypage/src/main/res/values/strings.xml b/feature/mypage/src/main/res/values/strings.xml index 35ccc510..f926a9b5 100644 --- a/feature/mypage/src/main/res/values/strings.xml +++ b/feature/mypage/src/main/res/values/strings.xml @@ -19,6 +19,7 @@ 취소 로그아웃 + 탈퇴하시겠습니까? 탈퇴 \ No newline at end of file diff --git a/remote/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageRemoteDataSourceImpl.kt b/remote/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageRemoteDataSourceImpl.kt index ce99f5a6..6f58a737 100644 --- a/remote/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageRemoteDataSourceImpl.kt +++ b/remote/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageRemoteDataSourceImpl.kt @@ -13,7 +13,6 @@ class MypageRemoteDataSourceImpl @Inject constructor( ) : MypageRemoteDataSource { override suspend fun getUserInfo(): GetUserInfoResponseDto { val user = mypageService.getUserInfo().data - Log.d("getUser ", user.nickname) return user } @@ -28,4 +27,7 @@ class MypageRemoteDataSourceImpl @Inject constructor( override suspend fun getWithdrawList(): GetWithdrawListResponseDto = mypageService.getWithdrawList().data + + override suspend fun deleteUser() = + mypageService.deleteUser() } diff --git a/remote/mypage/src/main/java/com/teamsolply/solply/mypage/service/MypageService.kt b/remote/mypage/src/main/java/com/teamsolply/solply/mypage/service/MypageService.kt index 8ef33d8f..278fb93a 100644 --- a/remote/mypage/src/main/java/com/teamsolply/solply/mypage/service/MypageService.kt +++ b/remote/mypage/src/main/java/com/teamsolply/solply/mypage/service/MypageService.kt @@ -6,6 +6,8 @@ import com.teamsolply.solply.mypage.dto.response.GetWithdrawListResponseDto import com.teamsolply.solply.mypage.dto.response.NicknameDuplicateResponseDto import com.teamsolply.solply.mypage.dto.response.PlaceListResponseDto import com.teamsolply.solply.network.model.BaseResponse +import com.teamsolply.solply.network.model.NullableBaseResponse +import retrofit2.http.DELETE import retrofit2.http.GET import retrofit2.http.Query @@ -29,4 +31,7 @@ interface MypageService { @GET("api/users/withdraw/reasons") suspend fun getWithdrawList(): BaseResponse + + @DELETE("api/users/withdraw") + suspend fun deleteUser(): NullableBaseResponse } From e39c1e73dc7ddb557b273c8ea78581519bb55ba6 Mon Sep 17 00:00:00 2001 From: ImHyungsuk Date: Sat, 11 Oct 2025 03:02:34 +0900 Subject: [PATCH 03/10] =?UTF-8?q?feature#149=20=ED=9A=8C=EC=9B=90=ED=83=88?= =?UTF-8?q?=ED=87=B4=20=EB=92=A4=EB=A1=9C=EA=B0=80=EA=B8=B0=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../teamsolply/solply/mypage/withdraw/WithdrawContract.kt | 2 ++ .../com/teamsolply/solply/mypage/withdraw/WithdrawScreen.kt | 5 ++++- .../teamsolply/solply/mypage/withdraw/WithdrawViewModel.kt | 4 ++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawContract.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawContract.kt index 06540da0..598d63ea 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawContract.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawContract.kt @@ -16,6 +16,8 @@ data class WithdrawState( sealed interface WithdrawIntent : UiIntent { data object Init : WithdrawIntent + data object BackButtonClick : WithdrawIntent + data class WithdrawItemClick(val index: Int) : WithdrawIntent data object WithdrawButtonClick : WithdrawIntent data class WithdrawReasonInput(val reason: String) : WithdrawIntent diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawScreen.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawScreen.kt index 56112ca0..298f7a7c 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawScreen.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawScreen.kt @@ -70,6 +70,7 @@ fun WithdrawRoute( onWithdrawButtonClick = { viewModel.sendIntent(WithdrawIntent.WithdrawButtonClick) }, onDialogConfirmClick = { viewModel.sendIntent(WithdrawIntent.DialogConfirmClick) }, onDialogDismissClick = { viewModel.sendIntent(WithdrawIntent.DialogDismissClick) }, + onBackButtonClick = { viewModel.sendIntent(WithdrawIntent.BackButtonClick) }, modifier = Modifier.padding(paddingValues) ) } @@ -86,6 +87,7 @@ fun WithdrawScreen( onWithdrawButtonClick: () -> Unit, onDialogConfirmClick: () -> Unit, onDialogDismissClick: () -> Unit, + onBackButtonClick: () -> Unit, modifier: Modifier = Modifier ) { if (dialogState) { @@ -108,7 +110,7 @@ fun WithdrawScreen( item { SolplyTopBar( barText = stringResource(R.string.mypage_withdraw), - onBackButtonClick = {} + onBackButtonClick = onBackButtonClick ) } itemsIndexed(withdrawList) { index, item -> @@ -206,6 +208,7 @@ private fun WithdrawScreenPreview() { onDialogConfirmClick = {}, onTextFieldValueChange = {}, onDialogDismissClick = {}, + onBackButtonClick = {}, modifier = Modifier.fillMaxSize() ) } diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawViewModel.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawViewModel.kt index b11a4a94..00628d43 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawViewModel.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawViewModel.kt @@ -18,6 +18,10 @@ class WithdrawViewModel @Inject constructor( getWithdrawList() } + WithdrawIntent.BackButtonClick -> { + postSideEffect(WithdrawSideEffect.NavigateToBack) + } + is WithdrawIntent.WithdrawReasonInput -> { reduce { copy( From 66fb33c8bddc78d4e25b27cdc4611d991a3fd05f Mon Sep 17 00:00:00 2001 From: ImHyungsuk Date: Sat, 11 Oct 2025 03:50:29 +0900 Subject: [PATCH 04/10] =?UTF-8?q?feature#149=20=EC=88=98=EC=A7=91=ED=95=A8?= =?UTF-8?q?=20ui=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../collection/component/CollectionScreen.kt | 40 +++++++++++++------ .../course/CourseCollectionScreen.kt | 13 ++++-- .../collection/place/PlaceCollectionScreen.kt | 23 ++++++----- 3 files changed, 51 insertions(+), 25 deletions(-) diff --git a/feature/collection/src/main/java/com/teamsolply/solply/collection/collection/component/CollectionScreen.kt b/feature/collection/src/main/java/com/teamsolply/solply/collection/collection/component/CollectionScreen.kt index 4ec0e60f..c2b6115f 100644 --- a/feature/collection/src/main/java/com/teamsolply/solply/collection/collection/component/CollectionScreen.kt +++ b/feature/collection/src/main/java/com/teamsolply/solply/collection/collection/component/CollectionScreen.kt @@ -6,12 +6,14 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.lazy.grid.GridCells +import androidx.compose.foundation.lazy.grid.GridItemSpan import androidx.compose.foundation.lazy.grid.LazyGridScope import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.teamsolply.solply.collection.R import com.teamsolply.solply.designsystem.component.dialog.SolplyConfirmDialog @@ -24,10 +26,6 @@ fun CollectionScreen( onBackButtonClick: () -> Unit, onDialogConfirmClick: () -> Unit, onDialogDismissClick: () -> Unit, - selectMode: Boolean, - onSelectButtonClick: () -> Unit, - onDeleteButtonClick: () -> Unit, - onCancelButtonClick: () -> Unit, dialogState: Boolean, content: LazyGridScope.() -> Unit, modifier: Modifier = Modifier @@ -52,20 +50,38 @@ fun CollectionScreen( barText = town, onBackButtonClick = { onBackButtonClick() } ) - SelectModeBar( - selectMode = selectMode, - onSelectButtonClick = onSelectButtonClick, - onDeleteButtonClick = onDeleteButtonClick, - onCancelButtonClick = onCancelButtonClick - ) LazyVerticalGrid( - modifier = modifier + modifier = Modifier .fillMaxSize(), columns = GridCells.Fixed(2), verticalArrangement = Arrangement.spacedBy(10.dp), horizontalArrangement = Arrangement.Center, - contentPadding = PaddingValues(top = 16.dp, start = 16.dp, end = 16.dp), + contentPadding = PaddingValues(start = 16.dp, end = 16.dp), content = content ) } } + +@Preview +@Composable +private fun CollectionScreenPreview() { + SolplyTheme { + CollectionScreen( + town = "", + onBackButtonClick = {}, + onDialogConfirmClick = {}, + onDialogDismissClick = {}, + content = { + item(span = { GridItemSpan(maxLineSpan) }) { + SelectModeBar( + selectMode = false, + onSelectButtonClick = { }, + onDeleteButtonClick = { }, + onCancelButtonClick = { } + ) + } + }, + dialogState = false + ) + } +} diff --git a/feature/collection/src/main/java/com/teamsolply/solply/collection/collection/course/CourseCollectionScreen.kt b/feature/collection/src/main/java/com/teamsolply/solply/collection/collection/course/CourseCollectionScreen.kt index 3cc1385c..96d291cc 100644 --- a/feature/collection/src/main/java/com/teamsolply/solply/collection/collection/course/CourseCollectionScreen.kt +++ b/feature/collection/src/main/java/com/teamsolply/solply/collection/collection/course/CourseCollectionScreen.kt @@ -19,6 +19,7 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.teamsolply.solply.collection.R import com.teamsolply.solply.collection.collection.component.CollectionScreen +import com.teamsolply.solply.collection.collection.component.SelectModeBar import com.teamsolply.solply.designsystem.component.card.SolplyCourseCard import com.teamsolply.solply.model.MapsType import com.teamsolply.solply.ui.extension.customClickable @@ -61,12 +62,16 @@ fun CourseCollectionRoute( onBackButtonClick = { viewModel.sendIntent(CourseCollectionIntent.BackButtonClick) }, onDialogConfirmClick = { viewModel.sendIntent(CourseCollectionIntent.DialogConfirmClick) }, onDialogDismissClick = { viewModel.sendIntent(CourseCollectionIntent.DialogDismissClick) }, - selectMode = uiState.selectMode, - onSelectButtonClick = { viewModel.sendIntent(CourseCollectionIntent.SelectButtonClick) }, - onDeleteButtonClick = { viewModel.sendIntent(CourseCollectionIntent.DeleteButtonClick) }, - onCancelButtonClick = { viewModel.sendIntent(CourseCollectionIntent.CancelButtonClick) }, dialogState = uiState.dialogState, content = { + item(span = { GridItemSpan(maxLineSpan) }) { + SelectModeBar( + selectMode = uiState.selectMode, + onSelectButtonClick = { viewModel.sendIntent(CourseCollectionIntent.SelectButtonClick) }, + onDeleteButtonClick = { viewModel.sendIntent(CourseCollectionIntent.DeleteButtonClick) }, + onCancelButtonClick = { viewModel.sendIntent(CourseCollectionIntent.CancelButtonClick) } + ) + } itemsIndexed(uiState.courses) { index, it -> Box( modifier = Modifier diff --git a/feature/collection/src/main/java/com/teamsolply/solply/collection/collection/place/PlaceCollectionScreen.kt b/feature/collection/src/main/java/com/teamsolply/solply/collection/collection/place/PlaceCollectionScreen.kt index 0d2cff64..c1fb21d5 100644 --- a/feature/collection/src/main/java/com/teamsolply/solply/collection/collection/place/PlaceCollectionScreen.kt +++ b/feature/collection/src/main/java/com/teamsolply/solply/collection/collection/place/PlaceCollectionScreen.kt @@ -19,6 +19,7 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.teamsolply.solply.collection.R import com.teamsolply.solply.collection.collection.component.CollectionScreen +import com.teamsolply.solply.collection.collection.component.SelectModeBar import com.teamsolply.solply.designsystem.component.card.SolplyPlaceCard import com.teamsolply.solply.model.MapsType import com.teamsolply.solply.ui.extension.customClickable @@ -61,12 +62,16 @@ fun PlaceCollectionRoute( onBackButtonClick = { viewModel.sendIntent(PlaceCollectionIntent.BackButtonClick) }, onDialogConfirmClick = { viewModel.sendIntent(PlaceCollectionIntent.DialogConfirmClick) }, onDialogDismissClick = { viewModel.sendIntent(PlaceCollectionIntent.DialogDismissClick) }, - selectMode = uiState.selectMode, - onSelectButtonClick = { viewModel.sendIntent(PlaceCollectionIntent.SelectButtonClick) }, - onDeleteButtonClick = { viewModel.sendIntent(PlaceCollectionIntent.DeleteButtonClick) }, - onCancelButtonClick = { viewModel.sendIntent(PlaceCollectionIntent.CancelButtonClick) }, dialogState = uiState.dialogState, content = { + item(span = { GridItemSpan(maxLineSpan) }) { + SelectModeBar( + selectMode = uiState.selectMode, + onSelectButtonClick = { viewModel.sendIntent(PlaceCollectionIntent.SelectButtonClick) }, + onDeleteButtonClick = { viewModel.sendIntent(PlaceCollectionIntent.DeleteButtonClick) }, + onCancelButtonClick = { viewModel.sendIntent(PlaceCollectionIntent.CancelButtonClick) } + ) + } itemsIndexed(uiState.places) { index, it -> Box( modifier = Modifier @@ -95,11 +100,11 @@ fun PlaceCollectionRoute( saved = it.isSaved, touchable = false, modifier = - if (index % 2 == 0) { - Modifier.padding(end = 5.dp) - } else { - Modifier.padding(start = 5.dp) - } + if (index % 2 == 0) { + Modifier.padding(end = 5.dp) + } else { + Modifier.padding(start = 5.dp) + } ) } } From 898dc77750a144e3cbe45fc1427e1166bbdd587f Mon Sep 17 00:00:00 2001 From: ImHyungsuk Date: Sat, 11 Oct 2025 17:39:42 +0900 Subject: [PATCH 05/10] =?UTF-8?q?feature#149=20=EB=A1=9C=EA=B7=B8=EC=95=84?= =?UTF-8?q?=EC=9B=83=20&=20=ED=9A=8C=EC=9B=90=ED=83=88=ED=87=B4=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle.kts | 1 + data/mypage/build.gradle.kts | 1 + .../datasource/MypageLocalDataSource.kt | 5 ++++ .../datasource/MypageRemoteDataSource.kt | 3 +- .../dto/request/DeleteUserRequestDto.kt | 14 ++++++++++ .../mypage/repository/MypageRepositoryImpl.kt | 25 +++++++++++++++-- .../mypage/repository/MypageRepository.kt | 4 ++- .../com/teamsolply/solply/main/MainScreen.kt | 10 ++++++- .../solply/mypage/MypageContract.kt | 5 ++-- .../teamsolply/solply/mypage/MypageScreen.kt | 6 ++-- .../solply/mypage/MypageViewModel.kt | 20 +++++++------ .../mypage/navigation/MypageNavigation.kt | 2 ++ .../mypage/withdraw/WithdrawContract.kt | 2 +- .../solply/mypage/withdraw/WithdrawScreen.kt | 4 +-- .../mypage/withdraw/WithdrawViewModel.kt | 28 +++++++++++++------ .../withdraw/navigation/WithdrawNavigation.kt | 3 +- local/mypage/.gitignore | 1 + local/mypage/build.gradle.kts | 14 ++++++++++ .../datasource/MypageLocalDataSourceImpl.kt | 17 +++++++++++ .../solply/mypage/di/MypageLocalDataModule.kt | 18 ++++++++++++ .../datasource/MypageRemoteDataSourceImpl.kt | 6 ++-- .../solply/mypage/service/MypageService.kt | 10 +++++-- .../onboarding/service/OnBoardingService.kt | 4 +-- settings.gradle.kts | 1 + 24 files changed, 166 insertions(+), 38 deletions(-) create mode 100644 data/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageLocalDataSource.kt create mode 100644 data/mypage/src/main/java/com/teamsolply/solply/mypage/dto/request/DeleteUserRequestDto.kt create mode 100644 local/mypage/.gitignore create mode 100644 local/mypage/build.gradle.kts create mode 100644 local/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageLocalDataSourceImpl.kt create mode 100644 local/mypage/src/main/java/com/teamsolply/solply/mypage/di/MypageLocalDataModule.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index e52a3959..ee5adf20 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -59,6 +59,7 @@ dependencies { implementation(projects.data.search) implementation(projects.local.main) implementation(projects.local.oauth) + implementation(projects.local.mypage) implementation(projects.local.place) implementation(projects.remote.oauth) implementation(projects.remote.onboarding) diff --git a/data/mypage/build.gradle.kts b/data/mypage/build.gradle.kts index 0c25eb39..2f2b9695 100644 --- a/data/mypage/build.gradle.kts +++ b/data/mypage/build.gradle.kts @@ -7,5 +7,6 @@ android { } dependencies { + implementation(projects.core.datastore) implementation(projects.domain.mypage) } diff --git a/data/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageLocalDataSource.kt b/data/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageLocalDataSource.kt new file mode 100644 index 00000000..a1d65cd7 --- /dev/null +++ b/data/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageLocalDataSource.kt @@ -0,0 +1,5 @@ +package com.teamsolply.solply.mypage.datasource + +interface MypageLocalDataSource { + suspend fun saveAutoSignIn(autoSignIn: Boolean) +} \ No newline at end of file diff --git a/data/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageRemoteDataSource.kt b/data/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageRemoteDataSource.kt index 4c3bd3e8..9cacc42d 100644 --- a/data/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageRemoteDataSource.kt +++ b/data/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageRemoteDataSource.kt @@ -1,5 +1,6 @@ package com.teamsolply.solply.mypage.datasource +import com.teamsolply.solply.mypage.dto.request.DeleteUserRequestDto import com.teamsolply.solply.mypage.dto.response.GetPersonaListResponseDto import com.teamsolply.solply.mypage.dto.response.GetUserInfoResponseDto import com.teamsolply.solply.mypage.dto.response.GetWithdrawListResponseDto @@ -13,5 +14,5 @@ interface MypageRemoteDataSource { suspend fun getPersonaList(): GetPersonaListResponseDto suspend fun checkNicknameDuplicate(nickname: String): NicknameDuplicateResponseDto suspend fun getWithdrawList(): GetWithdrawListResponseDto - suspend fun deleteUser(): NullableBaseResponse + suspend fun deleteUser(deleteUserRequestDto: DeleteUserRequestDto): NullableBaseResponse } diff --git a/data/mypage/src/main/java/com/teamsolply/solply/mypage/dto/request/DeleteUserRequestDto.kt b/data/mypage/src/main/java/com/teamsolply/solply/mypage/dto/request/DeleteUserRequestDto.kt new file mode 100644 index 00000000..6ab57e71 --- /dev/null +++ b/data/mypage/src/main/java/com/teamsolply/solply/mypage/dto/request/DeleteUserRequestDto.kt @@ -0,0 +1,14 @@ +package com.teamsolply.solply.mypage.dto.request + +import com.teamsolply.solply.mypage.model.WithdrawType +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class DeleteUserRequestDto( + @SerialName("withdrawReason") + val withdrawType: WithdrawType, + + @SerialName("reasonText") + val reasonText: String +) diff --git a/data/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepositoryImpl.kt b/data/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepositoryImpl.kt index 8c268e25..a708ad8b 100644 --- a/data/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepositoryImpl.kt +++ b/data/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepositoryImpl.kt @@ -1,15 +1,20 @@ package com.teamsolply.solply.mypage.repository +import android.util.Log +import com.teamsolply.solply.mypage.datasource.MypageLocalDataSource import com.teamsolply.solply.mypage.datasource.MypageRemoteDataSource +import com.teamsolply.solply.mypage.dto.request.DeleteUserRequestDto import com.teamsolply.solply.mypage.dto.response.toDomain import com.teamsolply.solply.mypage.model.PersonaEntity import com.teamsolply.solply.mypage.model.PlaceInfoEntity import com.teamsolply.solply.mypage.model.UserInfo import com.teamsolply.solply.mypage.model.WithdrawEntity +import com.teamsolply.solply.mypage.model.WithdrawType import javax.inject.Inject class MypageRepositoryImpl @Inject constructor( - private val mypageRemoteDataSource: MypageRemoteDataSource + private val mypageRemoteDataSource: MypageRemoteDataSource, + private val mypageLocalDataSource: MypageLocalDataSource ) : MypageRepository { override suspend fun getUserInfo(): Result = runCatching { mypageRemoteDataSource.getUserInfo() @@ -57,7 +62,21 @@ class MypageRepositoryImpl @Inject constructor( } } - override suspend fun deleteUser(): Result = - runCatching { mypageRemoteDataSource.deleteUser() } + override suspend fun deleteUser(withdrawType: WithdrawType, reason: String): Result = + runCatching { + Log.d("withdraw: ","repo impl start") + mypageRemoteDataSource.deleteUser( + DeleteUserRequestDto( + withdrawType = withdrawType, + reasonText = reason + ) + ) + } + + + override suspend fun saveAutoSignIn(autoSignIn: Boolean): Result = + runCatching { + mypageLocalDataSource.saveAutoSignIn(autoSignIn) + } } diff --git a/domain/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepository.kt b/domain/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepository.kt index 56ec579d..e390e265 100644 --- a/domain/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepository.kt +++ b/domain/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepository.kt @@ -4,6 +4,7 @@ import com.teamsolply.solply.mypage.model.PersonaEntity import com.teamsolply.solply.mypage.model.PlaceInfoEntity import com.teamsolply.solply.mypage.model.UserInfo import com.teamsolply.solply.mypage.model.WithdrawEntity +import com.teamsolply.solply.mypage.model.WithdrawType interface MypageRepository { suspend fun getUserInfo(): Result @@ -11,5 +12,6 @@ interface MypageRepository { suspend fun getPersonaList(): Result> suspend fun checkNicknameDuplicate(nickname: String): Result suspend fun getWithdrawList(): Result> - suspend fun deleteUser(): Result + suspend fun saveAutoSignIn(autoSignIn: Boolean): Result + suspend fun deleteUser(withdrawType: WithdrawType, reason: String): Result } diff --git a/feature/main/src/main/java/com/teamsolply/solply/main/MainScreen.kt b/feature/main/src/main/java/com/teamsolply/solply/main/MainScreen.kt index 78c25c79..a60c97f9 100644 --- a/feature/main/src/main/java/com/teamsolply/solply/main/MainScreen.kt +++ b/feature/main/src/main/java/com/teamsolply/solply/main/MainScreen.kt @@ -344,6 +344,10 @@ internal fun MainScreen( navigateToWithdraw = { val navOptions = navOptions { } navigator.navigateToWithdraw(navOptions) + }, + navigateToOauth = { + val navOptions = navOptions { } + navigator.navigateToOauth(navOptions) } ) profileNavGraph( @@ -359,7 +363,11 @@ internal fun MainScreen( ) withdrawNavGraph( paddingValues = innerPadding, - navigateToBack = navigator::navigateToBack + navigateToBack = navigator::navigateToBack, + navigateToOauth = { + val navOptions = navOptions { } + navigator.navigateToOauth(navOptions) + } ) favoriteTownNavGraph( paddingValues = innerPadding, diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageContract.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageContract.kt index 1504a26a..e423a88e 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageContract.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageContract.kt @@ -25,8 +25,8 @@ sealed interface MypageIntent : UiIntent { data object LogOutButtonClick : MypageIntent - data object DialogConfirmClick : MypageIntent - data object DialogDismissClick : MypageIntent + data object LogOutDialogConfirmClick : MypageIntent + data object LogOutDialogDismissClick : MypageIntent data object ProfileEditClick : MypageIntent data object WithdrawClick : MypageIntent @@ -36,4 +36,5 @@ sealed interface MypageSideEffect : SideEffect { data object NavigateToBack : MypageSideEffect data object NavigateToProfile : MypageSideEffect data object NavigateToWithdraw : MypageSideEffect + data object NavigateToOauth : MypageSideEffect } diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageScreen.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageScreen.kt index 2a348f0a..b2ad7889 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageScreen.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageScreen.kt @@ -46,6 +46,7 @@ fun MypageRoute( navigateToBack: () -> Unit, navigateToProfile: () -> Unit, navigateToWithdraw: () -> Unit, + navigateToOauth: () -> Unit, viewModel: MypageViewModel = hiltViewModel() ) { val uiState by viewModel.uiState.collectAsStateWithLifecycle() @@ -60,6 +61,7 @@ fun MypageRoute( MypageSideEffect.NavigateToBack -> navigateToBack() MypageSideEffect.NavigateToProfile -> navigateToProfile() MypageSideEffect.NavigateToWithdraw -> navigateToWithdraw() + MypageSideEffect.NavigateToOauth -> navigateToOauth() } } } @@ -72,8 +74,8 @@ fun MypageRoute( onProfileEditClick = { viewModel.sendIntent(MypageIntent.ProfileEditClick) }, onLogOutClick = { viewModel.sendIntent(MypageIntent.LogOutButtonClick) }, onWithdrawClick = { viewModel.sendIntent(MypageIntent.WithdrawClick) }, - onDialogConfirmClick = { viewModel.sendIntent(MypageIntent.DialogConfirmClick) }, - onDialogDismissClick = { viewModel.sendIntent(MypageIntent.DialogDismissClick) }, + onDialogConfirmClick = { viewModel.sendIntent(MypageIntent.LogOutDialogConfirmClick) }, + onDialogDismissClick = { viewModel.sendIntent(MypageIntent.LogOutDialogDismissClick) }, modifier = Modifier.padding(paddingValues) ) } diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageViewModel.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageViewModel.kt index bd9e411a..4cdc9994 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageViewModel.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageViewModel.kt @@ -1,5 +1,6 @@ package com.teamsolply.solply.mypage +import android.util.Log import androidx.lifecycle.viewModelScope import com.teamsolply.solply.mypage.repository.MypageRepository import com.teamsolply.solply.ui.base.BaseViewModel @@ -25,14 +26,19 @@ class MypageViewModel @Inject constructor( } } - MypageIntent.DialogConfirmClick -> { - fetchLogout() - reduce { - copy(dialogState = false) + MypageIntent.LogOutDialogConfirmClick -> { + viewModelScope.launch { + mypageRepository.saveAutoSignIn(false).onSuccess { + Log.d("logout:", "success") + reduce { + copy(dialogState = false) + } + postSideEffect(MypageSideEffect.NavigateToOauth) + } } } - MypageIntent.DialogDismissClick -> { + MypageIntent.LogOutDialogDismissClick -> { reduce { copy(dialogState = false) } @@ -72,8 +78,4 @@ class MypageViewModel @Inject constructor( } } } - - private fun fetchLogout() { - // TODO 로그아웃 api - } } diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/navigation/MypageNavigation.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/navigation/MypageNavigation.kt index b16028d9..ba34dd86 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/navigation/MypageNavigation.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/navigation/MypageNavigation.kt @@ -21,6 +21,7 @@ fun NavGraphBuilder.mypageNavGraph( navigateToBack: () -> Unit, navigateToProfile: () -> Unit, navigateToWithdraw: () -> Unit, + navigateToOauth: () -> Unit, paddingValues: PaddingValues ) { composable { backStackEntry -> @@ -30,6 +31,7 @@ fun NavGraphBuilder.mypageNavGraph( navigateToBack = navigateToBack, navigateToProfile = navigateToProfile, navigateToWithdraw = navigateToWithdraw, + navigateToOauth = navigateToOauth, viewModel = viewModel ) } diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawContract.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawContract.kt index 598d63ea..b8f7a92a 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawContract.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawContract.kt @@ -28,5 +28,5 @@ sealed interface WithdrawIntent : UiIntent { sealed interface WithdrawSideEffect : SideEffect { data object NavigateToBack : WithdrawSideEffect - data object NavigateToProfile : WithdrawSideEffect + data object NavigateToOauth : WithdrawSideEffect } diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawScreen.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawScreen.kt index 298f7a7c..b1ae9459 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawScreen.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawScreen.kt @@ -41,7 +41,7 @@ import kotlinx.coroutines.flow.collectLatest fun WithdrawRoute( paddingValues: PaddingValues, navigateToBack: () -> Unit, - navigateToProfile: () -> Unit, + navigateToOauth: () -> Unit, viewModel: WithdrawViewModel = hiltViewModel() ) { val uiState by viewModel.uiState.collectAsStateWithLifecycle() @@ -54,7 +54,7 @@ fun WithdrawRoute( viewModel.sideEffect.collectLatest { sideEffect -> when (sideEffect) { WithdrawSideEffect.NavigateToBack -> navigateToBack() - WithdrawSideEffect.NavigateToProfile -> navigateToProfile() + WithdrawSideEffect.NavigateToOauth -> navigateToOauth() } } } diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawViewModel.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawViewModel.kt index 00628d43..678c9967 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawViewModel.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawViewModel.kt @@ -1,5 +1,6 @@ package com.teamsolply.solply.mypage.withdraw +import android.util.Log import androidx.lifecycle.viewModelScope import com.teamsolply.solply.mypage.repository.MypageRepository import com.teamsolply.solply.ui.base.BaseViewModel @@ -48,7 +49,24 @@ class WithdrawViewModel @Inject constructor( } } - WithdrawIntent.DialogConfirmClick -> TODO() + WithdrawIntent.DialogConfirmClick -> { + val current = uiState.value + viewModelScope.launch { + Log.d("withdraw:", "success") + mypageRepository.deleteUser( + withdrawType = current.withdrawList[current.selectedIndex].withdrawType, + reason = current.withdrawReason + ).onSuccess { + mypageRepository.saveAutoSignIn(false).onSuccess { + reduce { + copy(dialogState = false) + } + postSideEffect(WithdrawSideEffect.NavigateToOauth) + } + } + } + } + WithdrawIntent.DialogDismissClick -> { reduce { copy(dialogState = false) @@ -66,12 +84,4 @@ class WithdrawViewModel @Inject constructor( } } } - - private fun fetchWithdraw() { - viewModelScope.launch { - mypageRepository.deleteUser().onSuccess { - // TODO - } - } - } } \ No newline at end of file diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/navigation/WithdrawNavigation.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/navigation/WithdrawNavigation.kt index 98aff51d..b04c70dc 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/navigation/WithdrawNavigation.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/navigation/WithdrawNavigation.kt @@ -19,6 +19,7 @@ fun NavController.navigateWithdraw( fun NavGraphBuilder.withdrawNavGraph( navigateToBack: () -> Unit, + navigateToOauth: () -> Unit, paddingValues: PaddingValues ) { composable { backStackEntry -> @@ -26,7 +27,7 @@ fun NavGraphBuilder.withdrawNavGraph( WithdrawRoute( paddingValues = paddingValues, navigateToBack = navigateToBack, - navigateToProfile = {}, + navigateToOauth = navigateToOauth, viewModel = viewModel ) } diff --git a/local/mypage/.gitignore b/local/mypage/.gitignore new file mode 100644 index 00000000..42afabfd --- /dev/null +++ b/local/mypage/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/local/mypage/build.gradle.kts b/local/mypage/build.gradle.kts new file mode 100644 index 00000000..6318d78b --- /dev/null +++ b/local/mypage/build.gradle.kts @@ -0,0 +1,14 @@ +plugins { + alias(libs.plugins.solply.local) +} + +android { + namespace = "com.teamsolply.solply.mypage" +} + +dependencies { + implementation(projects.core.model) + implementation(projects.core.datastore) + implementation(projects.data.mypage) + implementation(libs.bundles.datastore) +} diff --git a/local/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageLocalDataSourceImpl.kt b/local/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageLocalDataSourceImpl.kt new file mode 100644 index 00000000..2c50dfa5 --- /dev/null +++ b/local/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageLocalDataSourceImpl.kt @@ -0,0 +1,17 @@ +package com.teamsolply.solply.mypage.datasource + +import androidx.datastore.core.DataStore +import com.teamsolply.solply.datastore.SolplyTokenData +import javax.inject.Inject + +class MypageLocalDataSourceImpl @Inject constructor( + private val mypageLocalDataSource: DataStore +) : MypageLocalDataSource { + override suspend fun saveAutoSignIn(autoSignIn: Boolean) { + mypageLocalDataSource.updateData { old -> + old.copy( + autoSignIn = autoSignIn + ) + } + } +} \ No newline at end of file diff --git a/local/mypage/src/main/java/com/teamsolply/solply/mypage/di/MypageLocalDataModule.kt b/local/mypage/src/main/java/com/teamsolply/solply/mypage/di/MypageLocalDataModule.kt new file mode 100644 index 00000000..f84b8d46 --- /dev/null +++ b/local/mypage/src/main/java/com/teamsolply/solply/mypage/di/MypageLocalDataModule.kt @@ -0,0 +1,18 @@ +package com.teamsolply.solply.mypage.di + +import com.teamsolply.solply.mypage.datasource.MypageLocalDataSource +import com.teamsolply.solply.mypage.datasource.MypageLocalDataSourceImpl +import dagger.Binds +import dagger.Module +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import javax.inject.Singleton + + +@Module +@InstallIn(SingletonComponent::class) +abstract class MypageLocalDataModule { + @Binds + @Singleton + abstract fun bindsMypageLocalDataSource(mypageLocalDataSource: MypageLocalDataSourceImpl): MypageLocalDataSource +} \ No newline at end of file diff --git a/remote/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageRemoteDataSourceImpl.kt b/remote/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageRemoteDataSourceImpl.kt index 6f58a737..04fe87ce 100644 --- a/remote/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageRemoteDataSourceImpl.kt +++ b/remote/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageRemoteDataSourceImpl.kt @@ -1,11 +1,13 @@ package com.teamsolply.solply.mypage.datasource import android.util.Log +import com.teamsolply.solply.mypage.dto.request.DeleteUserRequestDto import com.teamsolply.solply.mypage.dto.response.GetPersonaListResponseDto import com.teamsolply.solply.mypage.dto.response.GetUserInfoResponseDto import com.teamsolply.solply.mypage.dto.response.GetWithdrawListResponseDto import com.teamsolply.solply.mypage.dto.response.NicknameDuplicateResponseDto import com.teamsolply.solply.mypage.service.MypageService +import com.teamsolply.solply.network.model.NullableBaseResponse import javax.inject.Inject class MypageRemoteDataSourceImpl @Inject constructor( @@ -28,6 +30,6 @@ class MypageRemoteDataSourceImpl @Inject constructor( override suspend fun getWithdrawList(): GetWithdrawListResponseDto = mypageService.getWithdrawList().data - override suspend fun deleteUser() = - mypageService.deleteUser() + override suspend fun deleteUser(deleteUserRequestDto: DeleteUserRequestDto) = + mypageService.deleteUser(deleteUserRequestDto) } diff --git a/remote/mypage/src/main/java/com/teamsolply/solply/mypage/service/MypageService.kt b/remote/mypage/src/main/java/com/teamsolply/solply/mypage/service/MypageService.kt index 278fb93a..5865575b 100644 --- a/remote/mypage/src/main/java/com/teamsolply/solply/mypage/service/MypageService.kt +++ b/remote/mypage/src/main/java/com/teamsolply/solply/mypage/service/MypageService.kt @@ -1,5 +1,6 @@ package com.teamsolply.solply.mypage.service +import com.teamsolply.solply.mypage.dto.request.DeleteUserRequestDto import com.teamsolply.solply.mypage.dto.response.GetPersonaListResponseDto import com.teamsolply.solply.mypage.dto.response.GetUserInfoResponseDto import com.teamsolply.solply.mypage.dto.response.GetWithdrawListResponseDto @@ -7,8 +8,11 @@ import com.teamsolply.solply.mypage.dto.response.NicknameDuplicateResponseDto import com.teamsolply.solply.mypage.dto.response.PlaceListResponseDto import com.teamsolply.solply.network.model.BaseResponse import com.teamsolply.solply.network.model.NullableBaseResponse +import retrofit2.http.Body import retrofit2.http.DELETE import retrofit2.http.GET +import retrofit2.http.HTTP +import retrofit2.http.POST import retrofit2.http.Query interface MypageService { @@ -32,6 +36,8 @@ interface MypageService { @GET("api/users/withdraw/reasons") suspend fun getWithdrawList(): BaseResponse - @DELETE("api/users/withdraw") - suspend fun deleteUser(): NullableBaseResponse + @HTTP(method = "DELETE", path = "api/users/withdraw", hasBody = true) + suspend fun deleteUser( + @Body deleteUserRequestDto: DeleteUserRequestDto + ): NullableBaseResponse } diff --git a/remote/onboarding/src/main/java/com/teamsolply/solply/onboarding/service/OnBoardingService.kt b/remote/onboarding/src/main/java/com/teamsolply/solply/onboarding/service/OnBoardingService.kt index 5516a3b1..96487473 100644 --- a/remote/onboarding/src/main/java/com/teamsolply/solply/onboarding/service/OnBoardingService.kt +++ b/remote/onboarding/src/main/java/com/teamsolply/solply/onboarding/service/OnBoardingService.kt @@ -13,7 +13,7 @@ import retrofit2.http.Query interface OnBoardingService { - @GET("api/onboarding/questions/persona") + @GET("api/users/persona") suspend fun getPersonaQuestions(): BaseResponse @GET("api/towns") @@ -24,7 +24,7 @@ interface OnBoardingService { @Query("nickname") nickname: String ): BaseResponse - @PATCH("api/onboarding/users") + @PATCH("api/users/onboarding") suspend fun patchUserInfo( @Body patchUserInfoRequestDto: PatchUserInfoRequestDto ): BaseResponse diff --git a/settings.gradle.kts b/settings.gradle.kts index 9cbb5d51..edaae962 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -53,6 +53,7 @@ include(":data:mypage") include(":data:search") include(":local:main") include(":local:oauth") +include(":local:mypage") include(":local:place") include(":remote:oauth") include(":remote:onboarding") From 9c698f4e7844f958583c371be07f94183816eb9f Mon Sep 17 00:00:00 2001 From: ImHyungsuk Date: Sat, 11 Oct 2025 17:49:17 +0900 Subject: [PATCH 06/10] =?UTF-8?q?feature#149=20=EB=A7=88=EC=9D=B4=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EB=82=B4=EA=B0=80=20=EB=93=B1=EB=A1=9D?= =?UTF-8?q?=ED=95=9C=20=EC=9E=A5=EC=86=8C=20=EB=AA=A9=EB=A1=9D=20=EA=B0=84?= =?UTF-8?q?=EA=B2=A9=20=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solply/mypage/component/SavedPlaceListContainer.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/component/SavedPlaceListContainer.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/component/SavedPlaceListContainer.kt index 1ecfdcbd..839d9bbf 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/component/SavedPlaceListContainer.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/component/SavedPlaceListContainer.kt @@ -1,5 +1,6 @@ package com.teamsolply.solply.mypage.component +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.size import androidx.compose.foundation.lazy.LazyRow @@ -19,7 +20,8 @@ fun SavedPlaceListContainer( ) { LazyRow( modifier = modifier - .fillMaxWidth() + .fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(16.dp) ) { items(savedPlaceList) { SolplyPlaceCard( From 313065375976aeb7fe557fc84b7bc680656561eb Mon Sep 17 00:00:00 2001 From: ImHyungsuk Date: Sat, 11 Oct 2025 18:43:16 +0900 Subject: [PATCH 07/10] =?UTF-8?q?feature#149=20=EB=A7=88=EC=9D=B4=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EB=82=B4=EA=B0=80=20=EB=93=B1=EB=A1=9D?= =?UTF-8?q?=ED=95=9C=20=EC=9E=A5=EC=86=8C=20=EC=A0=84=EC=B2=B4=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20ui=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solply/mypage/MypageContract.kt | 5 ++ .../teamsolply/solply/mypage/MypageScreen.kt | 63 +++++++++---- .../solply/mypage/MypageViewModel.kt | 17 +++- .../mypage/component/MypagePlaceAllScreen.kt | 89 +++++++++++++++++++ .../mypage/src/main/res/values/strings.xml | 2 + 5 files changed, 160 insertions(+), 16 deletions(-) create mode 100644 feature/mypage/src/main/java/com/teamsolply/solply/mypage/component/MypagePlaceAllScreen.kt diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageContract.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageContract.kt index e423a88e..b15606bb 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageContract.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageContract.kt @@ -17,17 +17,22 @@ data class MypageState( profileImageUrl = "" ), val placeList: List = emptyList(), + val placeAllState: Boolean = false, val dialogState: Boolean = false ) : UiState sealed interface MypageIntent : UiIntent { data object Init : MypageIntent + data object MypageBackButtonClick : MypageIntent + data object PlaceAllBackButtonClick : MypageIntent + data object LogOutButtonClick : MypageIntent data object LogOutDialogConfirmClick : MypageIntent data object LogOutDialogDismissClick : MypageIntent + data object PlaceAllClick : MypageIntent data object ProfileEditClick : MypageIntent data object WithdrawClick : MypageIntent } diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageScreen.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageScreen.kt index b2ad7889..a452f5dc 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageScreen.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageScreen.kt @@ -33,6 +33,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.teamsolply.solply.designsystem.component.dialog.SolplyConfirmDialog import com.teamsolply.solply.designsystem.theme.SolplyTheme import com.teamsolply.solply.mypage.component.EmptyPlaceContainer +import com.teamsolply.solply.mypage.component.MypagePlaceAllScreen import com.teamsolply.solply.mypage.component.MypageSettingItem import com.teamsolply.solply.mypage.component.SavedPlaceListContainer import com.teamsolply.solply.mypage.model.PlaceInfoEntity @@ -65,19 +66,26 @@ fun MypageRoute( } } } - - MypageScreen( - nickname = uiState.userInfo.nickname, - savedPlaceList = uiState.placeList, - dialogState = uiState.dialogState, - onBackButtonClick = navigateToBack, - onProfileEditClick = { viewModel.sendIntent(MypageIntent.ProfileEditClick) }, - onLogOutClick = { viewModel.sendIntent(MypageIntent.LogOutButtonClick) }, - onWithdrawClick = { viewModel.sendIntent(MypageIntent.WithdrawClick) }, - onDialogConfirmClick = { viewModel.sendIntent(MypageIntent.LogOutDialogConfirmClick) }, - onDialogDismissClick = { viewModel.sendIntent(MypageIntent.LogOutDialogDismissClick) }, - modifier = Modifier.padding(paddingValues) - ) + if (uiState.placeAllState) { + MypagePlaceAllScreen( + placeList = uiState.placeList, + onBackButtonClick = { viewModel.sendIntent(MypageIntent.PlaceAllBackButtonClick) }, + modifier = Modifier.padding(paddingValues) + ) + } else + MypageScreen( + nickname = uiState.userInfo.nickname, + savedPlaceList = uiState.placeList.take(3), + dialogState = uiState.dialogState, + onBackButtonClick = { viewModel.sendIntent(MypageIntent.MypageBackButtonClick) }, + onProfileEditClick = { viewModel.sendIntent(MypageIntent.ProfileEditClick) }, + onAllClick = { viewModel.sendIntent(MypageIntent.PlaceAllClick) }, + onLogOutClick = { viewModel.sendIntent(MypageIntent.LogOutButtonClick) }, + onWithdrawClick = { viewModel.sendIntent(MypageIntent.WithdrawClick) }, + onDialogConfirmClick = { viewModel.sendIntent(MypageIntent.LogOutDialogConfirmClick) }, + onDialogDismissClick = { viewModel.sendIntent(MypageIntent.LogOutDialogDismissClick) }, + modifier = Modifier.padding(paddingValues) + ) } @Composable @@ -87,6 +95,7 @@ fun MypageScreen( dialogState: Boolean, onBackButtonClick: () -> Unit, onProfileEditClick: () -> Unit, + onAllClick: () -> Unit, onLogOutClick: () -> Unit, onWithdrawClick: () -> Unit, onDialogConfirmClick: () -> Unit, @@ -177,13 +186,36 @@ fun MypageScreen( Row( modifier = Modifier .fillMaxWidth() - .padding(horizontal = 20.dp, vertical = 16.dp) + .padding(horizontal = 20.dp, vertical = 16.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween ) { Text( - text = "내가 등록한 장소", + text = stringResource(R.string.mypage_place), color = SolplyTheme.colors.black, style = SolplyTheme.typography.body16M ) + if (savedPlaceList.isNotEmpty()) { + Row( + modifier = Modifier + .customClickable( + rippleEnabled = false, + onClick = onAllClick + ), + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = stringResource(R.string.mypage_place_all), + style = SolplyTheme.typography.body14R, + color = SolplyTheme.colors.gray600 + ) + Icon( + painter = painterResource(com.teamsolply.solply.designsystem.R.drawable.ic_next_arrow), + contentDescription = "", + tint = SolplyTheme.colors.gray600 + ) + } + } } if (savedPlaceList.isEmpty()) { EmptyPlaceContainer( @@ -260,6 +292,7 @@ private fun MypageScreenPreview() { dialogState = false, onBackButtonClick = {}, onProfileEditClick = {}, + onAllClick = {}, onLogOutClick = {}, onWithdrawClick = {}, onDialogConfirmClick = {}, diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageViewModel.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageViewModel.kt index 4cdc9994..92f9e33a 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageViewModel.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageViewModel.kt @@ -18,6 +18,10 @@ class MypageViewModel @Inject constructor( when (intent) { MypageIntent.Init -> getInitInfo() + MypageIntent.MypageBackButtonClick -> { + postSideEffect(MypageSideEffect.NavigateToBack) + } + MypageIntent.LogOutButtonClick -> { reduce { copy( @@ -29,7 +33,6 @@ class MypageViewModel @Inject constructor( MypageIntent.LogOutDialogConfirmClick -> { viewModelScope.launch { mypageRepository.saveAutoSignIn(false).onSuccess { - Log.d("logout:", "success") reduce { copy(dialogState = false) } @@ -44,6 +47,18 @@ class MypageViewModel @Inject constructor( } } + MypageIntent.PlaceAllClick -> { + reduce { + copy(placeAllState = true) + } + } + + MypageIntent.PlaceAllBackButtonClick -> { + reduce { + copy(placeAllState = false) + } + } + MypageIntent.ProfileEditClick -> { postSideEffect(MypageSideEffect.NavigateToProfile) } diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/component/MypagePlaceAllScreen.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/component/MypagePlaceAllScreen.kt new file mode 100644 index 00000000..2aa8efbd --- /dev/null +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/component/MypagePlaceAllScreen.kt @@ -0,0 +1,89 @@ +package com.teamsolply.solply.mypage.component + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.grid.GridCells +import androidx.compose.foundation.lazy.grid.GridItemSpan +import androidx.compose.foundation.lazy.grid.LazyVerticalGrid +import androidx.compose.foundation.lazy.grid.itemsIndexed +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import com.teamsolply.solply.designsystem.component.card.SolplyPlaceCard +import com.teamsolply.solply.designsystem.component.topbar.SolplyTopBar +import com.teamsolply.solply.designsystem.theme.SolplyTheme +import com.teamsolply.solply.mypage.R +import com.teamsolply.solply.mypage.model.PlaceInfoEntity +import com.teamsolply.solply.ui.extension.customClickable + +@Composable +fun MypagePlaceAllScreen( + placeList: List, + onBackButtonClick: () -> Unit, + modifier: Modifier = Modifier +) { + Column( + modifier + .fillMaxSize() + .background(color = SolplyTheme.colors.white), + verticalArrangement = Arrangement.Top, + horizontalAlignment = Alignment.CenterHorizontally + ) { + SolplyTopBar( + barText = stringResource(R.string.mypage_place), + onBackButtonClick = { onBackButtonClick() } + ) + LazyVerticalGrid( + modifier = Modifier + .fillMaxSize(), + columns = GridCells.Fixed(2), + verticalArrangement = Arrangement.spacedBy(10.dp), + horizontalArrangement = Arrangement.Center, + contentPadding = PaddingValues(start = 16.dp, end = 16.dp, top = 16.dp), + content = { + itemsIndexed(placeList) { index, it -> + Box( + modifier = Modifier + .fillMaxSize() + .customClickable( + rippleEnabled = false + ) { + }, + contentAlignment = if (index % 2 == 0) { + Alignment.CenterEnd + } else { + Alignment.CenterStart + } + ) { + SolplyPlaceCard( + name = it.placeName, + placeType = it.placeType, + imgRes = it.imageUrls, + selected = it.isSelected, + saved = it.isSaved, + touchable = false, + modifier = + if (index % 2 == 0) { + Modifier.padding(end = 5.dp) + } else { + Modifier.padding(start = 5.dp) + } + ) + } + } + item(span = { GridItemSpan(2) }) { + Spacer(modifier = Modifier.height(60.dp)) + } + } + ) + } +} \ No newline at end of file diff --git a/feature/mypage/src/main/res/values/strings.xml b/feature/mypage/src/main/res/values/strings.xml index f926a9b5..126a6477 100644 --- a/feature/mypage/src/main/res/values/strings.xml +++ b/feature/mypage/src/main/res/values/strings.xml @@ -2,6 +2,8 @@ 계정 설정 고객센터 + 내가 등록한 장소 + 전체보기 로그아웃 탈퇴하기 From 163b57e66d4c69c4a718cd5dd454178960a7592c Mon Sep 17 00:00:00 2001 From: ImHyungsuk Date: Sun, 12 Oct 2025 14:04:06 +0900 Subject: [PATCH 08/10] =?UTF-8?q?feature#149=20=EB=82=B4=EA=B0=80=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=ED=95=9C=20=EC=A0=95=EC=86=8C=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=EC=97=90=EC=84=9C=20=EC=A7=80=EB=8F=84=20=EB=84=A4?= =?UTF-8?q?=EB=B9=84=EA=B2=8C=EC=9D=B4=EC=85=98=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mypage/dto/response/PlaceListResponseDto.kt | 3 +++ .../solply/mypage/repository/MypageRepositoryImpl.kt | 5 +++-- .../teamsolply/solply/mypage/model/PlaceInfoEntity.kt | 1 + .../java/com/teamsolply/solply/main/MainScreen.kt | 9 +++++++++ .../com/teamsolply/solply/mypage/MypageContract.kt | 2 ++ .../java/com/teamsolply/solply/mypage/MypageScreen.kt | 11 +++++++++++ .../com/teamsolply/solply/mypage/MypageViewModel.kt | 5 +++++ .../solply/mypage/component/MypagePlaceAllScreen.kt | 3 +++ .../solply/mypage/navigation/MypageNavigation.kt | 2 ++ 9 files changed, 39 insertions(+), 2 deletions(-) diff --git a/data/mypage/src/main/java/com/teamsolply/solply/mypage/dto/response/PlaceListResponseDto.kt b/data/mypage/src/main/java/com/teamsolply/solply/mypage/dto/response/PlaceListResponseDto.kt index a9d1cf92..df91aa80 100644 --- a/data/mypage/src/main/java/com/teamsolply/solply/mypage/dto/response/PlaceListResponseDto.kt +++ b/data/mypage/src/main/java/com/teamsolply/solply/mypage/dto/response/PlaceListResponseDto.kt @@ -19,6 +19,9 @@ data class PlaceResponseDto( @SerialName("placeName") val placeName: String, + @SerialName("townId") + val townId: Long, + @SerialName("thumbnailImageUrl") val imageUrl: String, diff --git a/data/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepositoryImpl.kt b/data/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepositoryImpl.kt index a708ad8b..2301eee7 100644 --- a/data/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepositoryImpl.kt +++ b/data/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepositoryImpl.kt @@ -31,7 +31,8 @@ class MypageRepositoryImpl @Inject constructor( placeName = place.placeName, placeType = place.tag, imageUrls = place.imageUrl, - isSaved = place.isSaved + isSaved = place.isSaved, + townId = place.townId ) } } @@ -64,7 +65,7 @@ class MypageRepositoryImpl @Inject constructor( override suspend fun deleteUser(withdrawType: WithdrawType, reason: String): Result = runCatching { - Log.d("withdraw: ","repo impl start") + Log.d("withdraw: ", "repo impl start") mypageRemoteDataSource.deleteUser( DeleteUserRequestDto( withdrawType = withdrawType, diff --git a/domain/mypage/src/main/java/com/teamsolply/solply/mypage/model/PlaceInfoEntity.kt b/domain/mypage/src/main/java/com/teamsolply/solply/mypage/model/PlaceInfoEntity.kt index d391c0cc..5c65b931 100644 --- a/domain/mypage/src/main/java/com/teamsolply/solply/mypage/model/PlaceInfoEntity.kt +++ b/domain/mypage/src/main/java/com/teamsolply/solply/mypage/model/PlaceInfoEntity.kt @@ -6,6 +6,7 @@ data class PlaceInfoEntity( val placeId: Long, val placeName: String, val placeType: PlaceType, + val townId: Long, val imageUrls: String, val isSaved: Boolean, val isSelected: Boolean = false diff --git a/feature/main/src/main/java/com/teamsolply/solply/main/MainScreen.kt b/feature/main/src/main/java/com/teamsolply/solply/main/MainScreen.kt index a60c97f9..fe19db56 100644 --- a/feature/main/src/main/java/com/teamsolply/solply/main/MainScreen.kt +++ b/feature/main/src/main/java/com/teamsolply/solply/main/MainScreen.kt @@ -348,6 +348,15 @@ internal fun MainScreen( navigateToOauth = { val navOptions = navOptions { } navigator.navigateToOauth(navOptions) + }, + navigateToMaps = { mapsType, townId, placeId -> + val navOptions = navOptions {} + navigator.navigateToMaps( + mapsType = mapsType, + townId = townId, + placeId = placeId, + navOptions = navOptions + ) } ) profileNavGraph( diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageContract.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageContract.kt index b15606bb..9e44934c 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageContract.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageContract.kt @@ -26,6 +26,7 @@ sealed interface MypageIntent : UiIntent { data object MypageBackButtonClick : MypageIntent data object PlaceAllBackButtonClick : MypageIntent + data class PlaceCardClick(val placeId: Long, val townId: Long) : MypageIntent data object LogOutButtonClick : MypageIntent @@ -42,4 +43,5 @@ sealed interface MypageSideEffect : SideEffect { data object NavigateToProfile : MypageSideEffect data object NavigateToWithdraw : MypageSideEffect data object NavigateToOauth : MypageSideEffect + data class NavigateToMap(val placeId: Long, val townId: Long) : MypageSideEffect } diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageScreen.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageScreen.kt index a452f5dc..55637270 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageScreen.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageScreen.kt @@ -32,6 +32,8 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.teamsolply.solply.designsystem.component.dialog.SolplyConfirmDialog import com.teamsolply.solply.designsystem.theme.SolplyTheme +import com.teamsolply.solply.model.MapsType +import com.teamsolply.solply.model.PlaceType import com.teamsolply.solply.mypage.component.EmptyPlaceContainer import com.teamsolply.solply.mypage.component.MypagePlaceAllScreen import com.teamsolply.solply.mypage.component.MypageSettingItem @@ -48,6 +50,7 @@ fun MypageRoute( navigateToProfile: () -> Unit, navigateToWithdraw: () -> Unit, navigateToOauth: () -> Unit, + navigateToMaps: (String, Long, Long) -> Unit, viewModel: MypageViewModel = hiltViewModel() ) { val uiState by viewModel.uiState.collectAsStateWithLifecycle() @@ -63,6 +66,11 @@ fun MypageRoute( MypageSideEffect.NavigateToProfile -> navigateToProfile() MypageSideEffect.NavigateToWithdraw -> navigateToWithdraw() MypageSideEffect.NavigateToOauth -> navigateToOauth() + is MypageSideEffect.NavigateToMap -> navigateToMaps( + MapsType.PLACE_DETAIL.name, + sideEffect.placeId, + sideEffect.townId + ) } } } @@ -70,6 +78,9 @@ fun MypageRoute( MypagePlaceAllScreen( placeList = uiState.placeList, onBackButtonClick = { viewModel.sendIntent(MypageIntent.PlaceAllBackButtonClick) }, + onPlaceCardClick = { placeId, townId -> + viewModel.sendIntent(MypageIntent.PlaceCardClick(placeId, townId)) + }, modifier = Modifier.padding(paddingValues) ) } else diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageViewModel.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageViewModel.kt index 92f9e33a..69da5077 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageViewModel.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageViewModel.kt @@ -59,6 +59,11 @@ class MypageViewModel @Inject constructor( } } + is MypageIntent.PlaceCardClick -> { + postSideEffect(MypageSideEffect.NavigateToMap(intent.placeId, intent.townId)) + + } + MypageIntent.ProfileEditClick -> { postSideEffect(MypageSideEffect.NavigateToProfile) } diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/component/MypagePlaceAllScreen.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/component/MypagePlaceAllScreen.kt index 2aa8efbd..ceb081a6 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/component/MypagePlaceAllScreen.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/component/MypagePlaceAllScreen.kt @@ -21,6 +21,7 @@ import androidx.compose.ui.unit.dp import com.teamsolply.solply.designsystem.component.card.SolplyPlaceCard import com.teamsolply.solply.designsystem.component.topbar.SolplyTopBar import com.teamsolply.solply.designsystem.theme.SolplyTheme +import com.teamsolply.solply.mypage.MypageIntent import com.teamsolply.solply.mypage.R import com.teamsolply.solply.mypage.model.PlaceInfoEntity import com.teamsolply.solply.ui.extension.customClickable @@ -29,6 +30,7 @@ import com.teamsolply.solply.ui.extension.customClickable fun MypagePlaceAllScreen( placeList: List, onBackButtonClick: () -> Unit, + onPlaceCardClick: (Long, Long) -> Unit, modifier: Modifier = Modifier ) { Column( @@ -57,6 +59,7 @@ fun MypagePlaceAllScreen( .customClickable( rippleEnabled = false ) { + onPlaceCardClick(it.townId, it.placeId) }, contentAlignment = if (index % 2 == 0) { Alignment.CenterEnd diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/navigation/MypageNavigation.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/navigation/MypageNavigation.kt index ba34dd86..0f565cb7 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/navigation/MypageNavigation.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/navigation/MypageNavigation.kt @@ -22,6 +22,7 @@ fun NavGraphBuilder.mypageNavGraph( navigateToProfile: () -> Unit, navigateToWithdraw: () -> Unit, navigateToOauth: () -> Unit, + navigateToMaps: (String, Long, Long) -> Unit, paddingValues: PaddingValues ) { composable { backStackEntry -> @@ -32,6 +33,7 @@ fun NavGraphBuilder.mypageNavGraph( navigateToProfile = navigateToProfile, navigateToWithdraw = navigateToWithdraw, navigateToOauth = navigateToOauth, + navigateToMaps = navigateToMaps, viewModel = viewModel ) } From 3254c3c29b6fdf3833af7e32458f2db1e88812f3 Mon Sep 17 00:00:00 2001 From: ImHyungsuk Date: Sun, 12 Oct 2025 14:38:22 +0900 Subject: [PATCH 09/10] =?UTF-8?q?feature#149=20=EB=82=B4=EA=B0=80=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=ED=95=9C=20=EC=A0=95=EC=86=8C=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20api=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mypage/datasource/MypageRemoteDataSource.kt | 1 + .../mypage/repository/MypageRepositoryImpl.kt | 17 ++++++++++++++++- .../mypage/repository/MypageRepository.kt | 1 + .../teamsolply/solply/mypage/MypageViewModel.kt | 13 ++++++++++++- .../datasource/MypageRemoteDataSourceImpl.kt | 3 +++ .../solply/mypage/service/MypageService.kt | 10 ++++++++-- 6 files changed, 41 insertions(+), 4 deletions(-) diff --git a/data/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageRemoteDataSource.kt b/data/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageRemoteDataSource.kt index 9cacc42d..f957db0e 100644 --- a/data/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageRemoteDataSource.kt +++ b/data/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageRemoteDataSource.kt @@ -15,4 +15,5 @@ interface MypageRemoteDataSource { suspend fun checkNicknameDuplicate(nickname: String): NicknameDuplicateResponseDto suspend fun getWithdrawList(): GetWithdrawListResponseDto suspend fun deleteUser(deleteUserRequestDto: DeleteUserRequestDto): NullableBaseResponse + suspend fun getReportPlaceList(userId: Long): PlaceListResponseDto } diff --git a/data/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepositoryImpl.kt b/data/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepositoryImpl.kt index 2301eee7..d1776091 100644 --- a/data/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepositoryImpl.kt +++ b/data/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepositoryImpl.kt @@ -37,6 +37,22 @@ class MypageRepositoryImpl @Inject constructor( } } + override suspend fun getReportPlaceList(userId: Long): Result> = + runCatching { + mypageRemoteDataSource.getReportPlaceList(userId = userId).placeList + }.mapCatching { placeList -> + placeList.map { place -> + PlaceInfoEntity( + placeId = place.placeId, + placeName = place.placeName, + placeType = place.tag, + imageUrls = place.imageUrl, + isSaved = place.isSaved, + townId = place.townId + ) + } + } + override suspend fun getPersonaList(): Result> = runCatching { mypageRemoteDataSource.getPersonaList().personaDtoList }.mapCatching { personaList -> @@ -65,7 +81,6 @@ class MypageRepositoryImpl @Inject constructor( override suspend fun deleteUser(withdrawType: WithdrawType, reason: String): Result = runCatching { - Log.d("withdraw: ", "repo impl start") mypageRemoteDataSource.deleteUser( DeleteUserRequestDto( withdrawType = withdrawType, diff --git a/domain/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepository.kt b/domain/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepository.kt index e390e265..78dc5cbf 100644 --- a/domain/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepository.kt +++ b/domain/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepository.kt @@ -9,6 +9,7 @@ import com.teamsolply.solply.mypage.model.WithdrawType interface MypageRepository { suspend fun getUserInfo(): Result suspend fun getPlaceList(townId: Long): Result> + suspend fun getReportPlaceList(userId: Long): Result> suspend fun getPersonaList(): Result> suspend fun checkNicknameDuplicate(nickname: String): Result suspend fun getWithdrawList(): Result> diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageViewModel.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageViewModel.kt index 69da5077..5daa9cfa 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageViewModel.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageViewModel.kt @@ -1,6 +1,5 @@ package com.teamsolply.solply.mypage -import android.util.Log import androidx.lifecycle.viewModelScope import com.teamsolply.solply.mypage.repository.MypageRepository import com.teamsolply.solply.ui.base.BaseViewModel @@ -98,4 +97,16 @@ class MypageViewModel @Inject constructor( } } } + + private fun getReportPlaceList(userId: Long) { + viewModelScope.launch { + mypageRepository.getReportPlaceList(userId).onSuccess { + reduce { + copy( + placeList = it.toPersistentList() + ) + } + } + } + } } diff --git a/remote/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageRemoteDataSourceImpl.kt b/remote/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageRemoteDataSourceImpl.kt index 04fe87ce..58a89bd5 100644 --- a/remote/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageRemoteDataSourceImpl.kt +++ b/remote/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageRemoteDataSourceImpl.kt @@ -21,6 +21,9 @@ class MypageRemoteDataSourceImpl @Inject constructor( override suspend fun getPlaceList(townId: Long) = mypageService.getPlaceList(townId = townId).data + override suspend fun getReportPlaceList(userId: Long) = + mypageService.getMyReportPlaceList(userId = userId).data + override suspend fun getPersonaList(): GetPersonaListResponseDto = mypageService.getPersonaList().data diff --git a/remote/mypage/src/main/java/com/teamsolply/solply/mypage/service/MypageService.kt b/remote/mypage/src/main/java/com/teamsolply/solply/mypage/service/MypageService.kt index 5865575b..036df224 100644 --- a/remote/mypage/src/main/java/com/teamsolply/solply/mypage/service/MypageService.kt +++ b/remote/mypage/src/main/java/com/teamsolply/solply/mypage/service/MypageService.kt @@ -9,10 +9,9 @@ import com.teamsolply.solply.mypage.dto.response.PlaceListResponseDto import com.teamsolply.solply.network.model.BaseResponse import com.teamsolply.solply.network.model.NullableBaseResponse import retrofit2.http.Body -import retrofit2.http.DELETE import retrofit2.http.GET import retrofit2.http.HTTP -import retrofit2.http.POST +import retrofit2.http.Path import retrofit2.http.Query interface MypageService { @@ -25,6 +24,13 @@ interface MypageService { @Query("isBookmarkSearch") isBookmarkedSearch: Boolean = true ): BaseResponse + @GET("api/users/{userId}/places") + suspend fun getMyReportPlaceList( + @Path("userId") userId: Long, + @Query("page") page: Int = 0, + @Query("size") size: Int = 20 + ): BaseResponse + @GET("api/users/persona") suspend fun getPersonaList(): BaseResponse From 39a6e2ceb3c33a4631f4e9de19ede497bfcabb6e Mon Sep 17 00:00:00 2001 From: ImHyungsuk Date: Sun, 12 Oct 2025 14:39:41 +0900 Subject: [PATCH 10/10] chore#149 apply ktlint --- .../mypage/datasource/MypageLocalDataSource.kt | 2 +- .../dto/response/GetWithdrawListResponseDto.kt | 2 +- .../mypage/repository/MypageRepositoryImpl.kt | 3 --- .../teamsolply/solply/mypage/model/WithdrawType.kt | 2 +- .../collection/place/PlaceCollectionScreen.kt | 10 +++++----- .../com/teamsolply/solply/mypage/MypageScreen.kt | 4 ++-- .../com/teamsolply/solply/mypage/MypageViewModel.kt | 1 - .../solply/mypage/component/MypagePlaceAllScreen.kt | 13 ++++++------- .../solply/mypage/withdraw/WithdrawContract.kt | 2 +- .../solply/mypage/withdraw/WithdrawScreen.kt | 4 ++-- .../solply/mypage/withdraw/WithdrawViewModel.kt | 2 +- .../withdraw/navigation/WithdrawNavigation.kt | 3 +-- .../mypage/datasource/MypageLocalDataSourceImpl.kt | 2 +- .../solply/mypage/di/MypageLocalDataModule.kt | 3 +-- .../mypage/datasource/MypageRemoteDataSourceImpl.kt | 2 -- 15 files changed, 23 insertions(+), 32 deletions(-) diff --git a/data/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageLocalDataSource.kt b/data/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageLocalDataSource.kt index a1d65cd7..e1dcd777 100644 --- a/data/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageLocalDataSource.kt +++ b/data/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageLocalDataSource.kt @@ -2,4 +2,4 @@ package com.teamsolply.solply.mypage.datasource interface MypageLocalDataSource { suspend fun saveAutoSignIn(autoSignIn: Boolean) -} \ No newline at end of file +} diff --git a/data/mypage/src/main/java/com/teamsolply/solply/mypage/dto/response/GetWithdrawListResponseDto.kt b/data/mypage/src/main/java/com/teamsolply/solply/mypage/dto/response/GetWithdrawListResponseDto.kt index 2e7540be..33ef986b 100644 --- a/data/mypage/src/main/java/com/teamsolply/solply/mypage/dto/response/GetWithdrawListResponseDto.kt +++ b/data/mypage/src/main/java/com/teamsolply/solply/mypage/dto/response/GetWithdrawListResponseDto.kt @@ -17,4 +17,4 @@ data class WithdrawResponseDto( @SerialName("description") val description: String -) \ No newline at end of file +) diff --git a/data/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepositoryImpl.kt b/data/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepositoryImpl.kt index d1776091..a5397b55 100644 --- a/data/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepositoryImpl.kt +++ b/data/mypage/src/main/java/com/teamsolply/solply/mypage/repository/MypageRepositoryImpl.kt @@ -1,6 +1,5 @@ package com.teamsolply.solply.mypage.repository -import android.util.Log import com.teamsolply.solply.mypage.datasource.MypageLocalDataSource import com.teamsolply.solply.mypage.datasource.MypageRemoteDataSource import com.teamsolply.solply.mypage.dto.request.DeleteUserRequestDto @@ -89,10 +88,8 @@ class MypageRepositoryImpl @Inject constructor( ) } - override suspend fun saveAutoSignIn(autoSignIn: Boolean): Result = runCatching { mypageLocalDataSource.saveAutoSignIn(autoSignIn) } - } diff --git a/domain/mypage/src/main/java/com/teamsolply/solply/mypage/model/WithdrawType.kt b/domain/mypage/src/main/java/com/teamsolply/solply/mypage/model/WithdrawType.kt index be6c6122..fbb7ad64 100644 --- a/domain/mypage/src/main/java/com/teamsolply/solply/mypage/model/WithdrawType.kt +++ b/domain/mypage/src/main/java/com/teamsolply/solply/mypage/model/WithdrawType.kt @@ -12,4 +12,4 @@ enum class WithdrawType( HATE_RECOMMEND("추천 콘텐츠가 나와 맞지 않아서"), USE_OTHER_SERVICE("다른 서비스를 사용하고 있습니다."), OTHERS("기타") -} \ No newline at end of file +} diff --git a/feature/collection/src/main/java/com/teamsolply/solply/collection/collection/place/PlaceCollectionScreen.kt b/feature/collection/src/main/java/com/teamsolply/solply/collection/collection/place/PlaceCollectionScreen.kt index c1fb21d5..a3c9130c 100644 --- a/feature/collection/src/main/java/com/teamsolply/solply/collection/collection/place/PlaceCollectionScreen.kt +++ b/feature/collection/src/main/java/com/teamsolply/solply/collection/collection/place/PlaceCollectionScreen.kt @@ -100,11 +100,11 @@ fun PlaceCollectionRoute( saved = it.isSaved, touchable = false, modifier = - if (index % 2 == 0) { - Modifier.padding(end = 5.dp) - } else { - Modifier.padding(start = 5.dp) - } + if (index % 2 == 0) { + Modifier.padding(end = 5.dp) + } else { + Modifier.padding(start = 5.dp) + } ) } } diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageScreen.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageScreen.kt index 55637270..bdbca4cc 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageScreen.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageScreen.kt @@ -33,7 +33,6 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.teamsolply.solply.designsystem.component.dialog.SolplyConfirmDialog import com.teamsolply.solply.designsystem.theme.SolplyTheme import com.teamsolply.solply.model.MapsType -import com.teamsolply.solply.model.PlaceType import com.teamsolply.solply.mypage.component.EmptyPlaceContainer import com.teamsolply.solply.mypage.component.MypagePlaceAllScreen import com.teamsolply.solply.mypage.component.MypageSettingItem @@ -83,7 +82,7 @@ fun MypageRoute( }, modifier = Modifier.padding(paddingValues) ) - } else + } else { MypageScreen( nickname = uiState.userInfo.nickname, savedPlaceList = uiState.placeList.take(3), @@ -97,6 +96,7 @@ fun MypageRoute( onDialogDismissClick = { viewModel.sendIntent(MypageIntent.LogOutDialogDismissClick) }, modifier = Modifier.padding(paddingValues) ) + } } @Composable diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageViewModel.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageViewModel.kt index 5daa9cfa..22060318 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageViewModel.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/MypageViewModel.kt @@ -60,7 +60,6 @@ class MypageViewModel @Inject constructor( is MypageIntent.PlaceCardClick -> { postSideEffect(MypageSideEffect.NavigateToMap(intent.placeId, intent.townId)) - } MypageIntent.ProfileEditClick -> { diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/component/MypagePlaceAllScreen.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/component/MypagePlaceAllScreen.kt index ceb081a6..83ae9ca3 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/component/MypagePlaceAllScreen.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/component/MypagePlaceAllScreen.kt @@ -21,7 +21,6 @@ import androidx.compose.ui.unit.dp import com.teamsolply.solply.designsystem.component.card.SolplyPlaceCard import com.teamsolply.solply.designsystem.component.topbar.SolplyTopBar import com.teamsolply.solply.designsystem.theme.SolplyTheme -import com.teamsolply.solply.mypage.MypageIntent import com.teamsolply.solply.mypage.R import com.teamsolply.solply.mypage.model.PlaceInfoEntity import com.teamsolply.solply.ui.extension.customClickable @@ -75,11 +74,11 @@ fun MypagePlaceAllScreen( saved = it.isSaved, touchable = false, modifier = - if (index % 2 == 0) { - Modifier.padding(end = 5.dp) - } else { - Modifier.padding(start = 5.dp) - } + if (index % 2 == 0) { + Modifier.padding(end = 5.dp) + } else { + Modifier.padding(start = 5.dp) + } ) } } @@ -89,4 +88,4 @@ fun MypagePlaceAllScreen( } ) } -} \ No newline at end of file +} diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawContract.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawContract.kt index b8f7a92a..51a74a72 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawContract.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawContract.kt @@ -10,7 +10,7 @@ data class WithdrawState( val selectedIndex: Int = -1, val withdrawReason: String = "", val buttonEnabled: Boolean = false, - val dialogState: Boolean = false, + val dialogState: Boolean = false ) : UiState sealed interface WithdrawIntent : UiIntent { diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawScreen.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawScreen.kt index b1ae9459..3f242120 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawScreen.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawScreen.kt @@ -147,7 +147,7 @@ fun WithdrawScreen( if (index == withdrawList.lastIndex && selectedIndex == withdrawList.lastIndex) { SolplyFixedReportTextField( value = withdrawReason, - onValueChange = { onTextFieldValueChange(it) }, + onValueChange = { onTextFieldValueChange(it) } ) } else { HorizontalDivider( @@ -212,4 +212,4 @@ private fun WithdrawScreenPreview() { modifier = Modifier.fillMaxSize() ) } -} \ No newline at end of file +} diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawViewModel.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawViewModel.kt index 678c9967..5e7737cb 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawViewModel.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/WithdrawViewModel.kt @@ -84,4 +84,4 @@ class WithdrawViewModel @Inject constructor( } } } -} \ No newline at end of file +} diff --git a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/navigation/WithdrawNavigation.kt b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/navigation/WithdrawNavigation.kt index b04c70dc..4f10c38a 100644 --- a/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/navigation/WithdrawNavigation.kt +++ b/feature/mypage/src/main/java/com/teamsolply/solply/mypage/withdraw/navigation/WithdrawNavigation.kt @@ -31,8 +31,7 @@ fun NavGraphBuilder.withdrawNavGraph( viewModel = viewModel ) } - } @Serializable -data object Withdraw : Route \ No newline at end of file +data object Withdraw : Route diff --git a/local/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageLocalDataSourceImpl.kt b/local/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageLocalDataSourceImpl.kt index 2c50dfa5..2ee7c1cc 100644 --- a/local/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageLocalDataSourceImpl.kt +++ b/local/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageLocalDataSourceImpl.kt @@ -14,4 +14,4 @@ class MypageLocalDataSourceImpl @Inject constructor( ) } } -} \ No newline at end of file +} diff --git a/local/mypage/src/main/java/com/teamsolply/solply/mypage/di/MypageLocalDataModule.kt b/local/mypage/src/main/java/com/teamsolply/solply/mypage/di/MypageLocalDataModule.kt index f84b8d46..02c880b0 100644 --- a/local/mypage/src/main/java/com/teamsolply/solply/mypage/di/MypageLocalDataModule.kt +++ b/local/mypage/src/main/java/com/teamsolply/solply/mypage/di/MypageLocalDataModule.kt @@ -8,11 +8,10 @@ import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import javax.inject.Singleton - @Module @InstallIn(SingletonComponent::class) abstract class MypageLocalDataModule { @Binds @Singleton abstract fun bindsMypageLocalDataSource(mypageLocalDataSource: MypageLocalDataSourceImpl): MypageLocalDataSource -} \ No newline at end of file +} diff --git a/remote/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageRemoteDataSourceImpl.kt b/remote/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageRemoteDataSourceImpl.kt index 58a89bd5..6cf675b0 100644 --- a/remote/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageRemoteDataSourceImpl.kt +++ b/remote/mypage/src/main/java/com/teamsolply/solply/mypage/datasource/MypageRemoteDataSourceImpl.kt @@ -1,13 +1,11 @@ package com.teamsolply.solply.mypage.datasource -import android.util.Log import com.teamsolply.solply.mypage.dto.request.DeleteUserRequestDto import com.teamsolply.solply.mypage.dto.response.GetPersonaListResponseDto import com.teamsolply.solply.mypage.dto.response.GetUserInfoResponseDto import com.teamsolply.solply.mypage.dto.response.GetWithdrawListResponseDto import com.teamsolply.solply.mypage.dto.response.NicknameDuplicateResponseDto import com.teamsolply.solply.mypage.service.MypageService -import com.teamsolply.solply.network.model.NullableBaseResponse import javax.inject.Inject class MypageRemoteDataSourceImpl @Inject constructor(