diff --git a/core/designsystem/src/main/java/com/umcspot/spot/designsystem/component/modal/AcceptModal.kt b/core/designsystem/src/main/java/com/umcspot/spot/designsystem/component/modal/AcceptModal.kt
index e4e3cc39..224e5098 100644
--- a/core/designsystem/src/main/java/com/umcspot/spot/designsystem/component/modal/AcceptModal.kt
+++ b/core/designsystem/src/main/java/com/umcspot/spot/designsystem/component/modal/AcceptModal.kt
@@ -18,6 +18,9 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.ColorFilter
+import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
@@ -33,17 +36,20 @@ import com.umcspot.spot.ui.extension.screenWidthDp
@Composable
fun AcceptModal(
+ painter: Painter,
+ painterTint: Color,
modalTitle : String,
- modalDes : String,
+ modalDes : String?,
okButtonText : String,
+ noButtonText: String?,
modifier: Modifier = Modifier,
onClick: () -> Unit = {},
- onDismiss:() -> Unit= {}
+ onDismiss:() -> Unit = {}
) {
Card(
modifier = modifier
.width(screenWidthDp(326.dp))
- .height(screenHeightDp(249.dp)),
+ .wrapContentHeight(),
shape = SpotShapes.Round,
colors = CardDefaults.elevatedCardColors(
containerColor = SpotTheme.colors.white
@@ -70,10 +76,11 @@ fun AcceptModal(
}
Image(
- painter = painterResource(R.drawable.ic_check),
+ painter = painter,
contentDescription = null,
modifier = Modifier
- .size(screenWidthDp(33.dp))
+ .size(screenWidthDp(33.dp)),
+ colorFilter = ColorFilter.tint(painterTint)
)
Spacer(Modifier.height(screenHeightDp(7.dp)))
@@ -88,25 +95,41 @@ fun AcceptModal(
Spacer(Modifier.height(screenHeightDp(20.dp)))
- Text(
- text = modalDes,
- style = SpotTheme.typography.regular_500,
- textAlign = TextAlign.Center
- )
+ if(modalDes != null) {
+ Text(
+ text = modalDes,
+ style = SpotTheme.typography.regular_500,
+ textAlign = TextAlign.Center
+ )
- Spacer(Modifier.height(screenHeightDp(20.dp)))
+ Spacer(Modifier.height(screenHeightDp(20.dp)))
+ }
- TextButton(
- modifier = Modifier
- .width(screenWidthDp(156.dp))
- .height(screenHeightDp(39.dp)),
- text = okButtonText,
- style = SpotTheme.typography.h5,
- onClick = onClick,
- shape = SpotShapes.Soft,
- state = TextButtonState.B500State,
- )
+ Row(horizontalArrangement = Arrangement.spacedBy(10.dp)) {
+ TextButton(
+ modifier = Modifier
+ .width(screenWidthDp(141.dp))
+ .height(screenHeightDp(39.dp)),
+ text = okButtonText,
+ style = SpotTheme.typography.h5,
+ onClick = onClick,
+ shape = SpotShapes.Soft,
+ state = TextButtonState.B500State,
+ )
+ if(noButtonText != null) {
+ TextButton(
+ modifier = Modifier
+ .width(screenWidthDp(141.dp))
+ .height(screenHeightDp(39.dp)),
+ text = noButtonText,
+ style = SpotTheme.typography.h5,
+ onClick = onDismiss,
+ shape = SpotShapes.Soft,
+ state = TextButtonState.G500State,
+ )
+ }
+ }
}
}
}
@@ -114,20 +137,26 @@ fun AcceptModal(
@Composable
fun AcceptDialog(
visible: Boolean,
+ painter: Painter = painterResource(R.drawable.ic_check),
+ painterTint: Color = Color.Unspecified,
modalTitle : String,
- modalDes : String,
+ modalDes : String?,
okButtonText : String,
+ noButtonText: String?,
onClick: () -> Unit,
onDismiss: () -> Unit,
) {
if (!visible) return
Dialog(onDismissRequest = onDismiss) {
AcceptModal(
+ painter = painter,
+ painterTint = painterTint,
modalTitle = modalTitle,
modalDes = modalDes,
okButtonText = okButtonText,
+ noButtonText = noButtonText,
onClick = onClick,
- onDismiss = onDismiss
+ onDismiss = onDismiss,
)
}
}
@@ -140,6 +169,7 @@ private fun AcceptDialog_Preview() {
visible = true,
modalTitle = "스터디원 신고 완료",
modalDes = "스터디원 신고가 완료되었어요.\n쾌적한 서비스 이용을 위해 항상 노력하겠습니다.",
+ noButtonText = "취소",
okButtonText = "확인",
onClick = {},
onDismiss = {}
diff --git a/core/designsystem/src/main/java/com/umcspot/spot/designsystem/component/modal/RejectModal.kt b/core/designsystem/src/main/java/com/umcspot/spot/designsystem/component/modal/RejectModal.kt
index bdb56ba1..58214489 100644
--- a/core/designsystem/src/main/java/com/umcspot/spot/designsystem/component/modal/RejectModal.kt
+++ b/core/designsystem/src/main/java/com/umcspot/spot/designsystem/component/modal/RejectModal.kt
@@ -18,6 +18,9 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.ColorFilter
+import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
@@ -27,6 +30,7 @@ import com.umcspot.spot.designsystem.R
import com.umcspot.spot.designsystem.component.button.TextButton
import com.umcspot.spot.designsystem.component.button.TextButtonState
import com.umcspot.spot.designsystem.shapes.SpotShapes
+import com.umcspot.spot.designsystem.theme.R500
import com.umcspot.spot.designsystem.theme.SpotTheme
import com.umcspot.spot.ui.extension.screenHeightDp
import com.umcspot.spot.ui.extension.screenWidthDp
@@ -34,10 +38,12 @@ import com.umcspot.spot.ui.extension.screenWidthDp
@Composable
fun RejectModal(
+ painter : Painter,
+ painterTint : Color,
modalTitle : String,
- modalDes : String,
+ modalDes : String?,
okButtonText : String,
- noButtonText : String,
+ noButtonText : String?,
modifier: Modifier = Modifier,
onClick: () -> Unit = {},
onCancel:() -> Unit= {},
@@ -46,7 +52,7 @@ fun RejectModal(
Card(
modifier = modifier
.width(screenWidthDp(326.dp))
- .height(screenHeightDp(227.dp)),
+ .wrapContentHeight(),
shape = SpotShapes.Round,
colors = CardDefaults.elevatedCardColors(
containerColor = SpotTheme.colors.white
@@ -73,10 +79,11 @@ fun RejectModal(
}
Image(
- painter = painterResource(R.drawable.emoji_sad),
+ painter = painter,
contentDescription = null,
modifier = Modifier
- .size(screenWidthDp(33.dp))
+ .size(screenWidthDp(33.dp)),
+ colorFilter = ColorFilter.tint(painterTint)
)
Spacer(Modifier.height(screenHeightDp(7.dp)))
@@ -90,13 +97,15 @@ fun RejectModal(
Spacer(Modifier.height(screenHeightDp(20.dp)))
- Text(
- text = modalDes,
- style = SpotTheme.typography.regular_500,
- textAlign = TextAlign.Center
- )
+ if(modalDes != null) {
+ Text(
+ text = modalDes,
+ style = SpotTheme.typography.regular_500,
+ textAlign = TextAlign.Center
+ )
- Spacer(Modifier.height(screenHeightDp(20.dp)))
+ Spacer(Modifier.height(screenHeightDp(20.dp)))
+ }
Row(horizontalArrangement = Arrangement.spacedBy(10.dp)) {
TextButton(
@@ -110,16 +119,18 @@ fun RejectModal(
state = TextButtonState.R500State,
)
- TextButton(
- modifier = Modifier
- .width(screenWidthDp(141.dp))
- .height(screenHeightDp(39.dp)),
- text = noButtonText,
- style = SpotTheme.typography.h5,
- onClick = onCancel,
- shape = SpotShapes.Soft,
- state = TextButtonState.G500State,
- )
+ if(noButtonText != null) {
+ TextButton(
+ modifier = Modifier
+ .width(screenWidthDp(141.dp))
+ .height(screenHeightDp(39.dp)),
+ text = noButtonText,
+ style = SpotTheme.typography.h5,
+ onClick = onCancel,
+ shape = SpotShapes.Soft,
+ state = TextButtonState.G500State,
+ )
+ }
}
}
}
@@ -128,17 +139,21 @@ fun RejectModal(
@Composable
fun RejectDialog(
visible: Boolean,
+ painter : Painter = painterResource(R.drawable.emoji_sad),
+ painterTint : Color = Color.Unspecified,
modalTitle : String,
- modalDes : String,
+ modalDes : String?,
okButtonText : String,
- noButtonText : String,
- onDismiss: () -> Unit,
+ noButtonText : String?,
+ onDismiss: () -> Unit = {},
onClick: () -> Unit,
- onCancel: () -> Unit
+ onCancel: () -> Unit = {}
) {
if (!visible) return
Dialog(onDismissRequest = onDismiss) {
RejectModal(
+ painter = painter,
+ painterTint = painterTint,
modalTitle = modalTitle,
modalDes = modalDes,
okButtonText = okButtonText,
@@ -156,6 +171,8 @@ private fun RejectDialog_Preview() {
SpotTheme {
RejectDialog(
visible = true,
+ painter = painterResource(R.drawable.emoji_sad),
+ painterTint = SpotTheme.colors.R500,
modalTitle = "나가시겠어요?",
modalDes = "지금 나가면, 쓰던 글은 저장되지 않아요.",
okButtonText = "네",
diff --git a/core/designsystem/src/main/java/com/umcspot/spot/designsystem/component/study/StudyItem.kt b/core/designsystem/src/main/java/com/umcspot/spot/designsystem/component/study/StudyItem.kt
index 8705c5d9..af59e3ba 100644
--- a/core/designsystem/src/main/java/com/umcspot/spot/designsystem/component/study/StudyItem.kt
+++ b/core/designsystem/src/main/java/com/umcspot/spot/designsystem/component/study/StudyItem.kt
@@ -206,7 +206,8 @@ private fun StudyListItemPreview() {
isLiked = false,
hitCount = 1200,
profileImageUrl = ImageRef.Name("spot_logo"),
- isOwner = false
+ isOwner = false,
+ isAlone = false
),
modifier = Modifier.padding(10.dp),
onClick = {},
diff --git a/core/designsystem/src/main/res/drawable/error.xml b/core/designsystem/src/main/res/drawable/error.xml
new file mode 100644
index 00000000..19080513
--- /dev/null
+++ b/core/designsystem/src/main/res/drawable/error.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/core/model/src/main/java/com/umcspot/spot/model/Global.kt b/core/model/src/main/java/com/umcspot/spot/model/Global.kt
index 7c65eb78..a032f4a1 100644
--- a/core/model/src/main/java/com/umcspot/spot/model/Global.kt
+++ b/core/model/src/main/java/com/umcspot/spot/model/Global.kt
@@ -63,8 +63,8 @@ enum class StudyTheme(
OTHER("기타");
companion object {
- fun from(value: String): StudyTheme? =
- values().firstOrNull { it.name == value }
+ fun from(value: String): StudyTheme =
+ StudyTheme.entries.first { it.name == value }
}
}
diff --git a/data/study/src/main/java/com/umcspot/spot/study/dto/response/StudyResponseDto.kt b/data/study/src/main/java/com/umcspot/spot/study/dto/response/StudyResponseDto.kt
index 0cba9d94..5acc50b8 100644
--- a/data/study/src/main/java/com/umcspot/spot/study/dto/response/StudyResponseDto.kt
+++ b/data/study/src/main/java/com/umcspot/spot/study/dto/response/StudyResponseDto.kt
@@ -45,6 +45,9 @@ data class Study (
@SerialName("isOwner")
val isOwner: Boolean,
+ @SerialName("isAlone")
+ val isAlone: Boolean,
+
@SerialName("hitCount")
val hitCount: Int = 0,
diff --git a/data/study/src/main/java/com/umcspot/spot/study/mapper/StudyMapper.kt b/data/study/src/main/java/com/umcspot/spot/study/mapper/StudyMapper.kt
index 8d05342e..c76f615d 100644
--- a/data/study/src/main/java/com/umcspot/spot/study/mapper/StudyMapper.kt
+++ b/data/study/src/main/java/com/umcspot/spot/study/mapper/StudyMapper.kt
@@ -29,6 +29,7 @@ fun Study.toDomain() : StudyResult =
likeCount = this.likeCount,
isLiked = this.isLiked,
isOwner = this.isOwner,
+ isAlone = this.isAlone,
hitCount = this.hitCount,
profileImageUrl = this.profileImageUrl.toImageRef()
)
diff --git a/data/user/src/main/java/com/umcspot/spot/user/datasource/UserDataSource.kt b/data/user/src/main/java/com/umcspot/spot/user/datasource/UserDataSource.kt
index 512286d7..dc3370b8 100644
--- a/data/user/src/main/java/com/umcspot/spot/user/datasource/UserDataSource.kt
+++ b/data/user/src/main/java/com/umcspot/spot/user/datasource/UserDataSource.kt
@@ -18,4 +18,6 @@ interface UserDataSource {
suspend fun getMyPageInfo() : BaseResponse
suspend fun getUserPreferredCategory() : BaseResponse
+
+ suspend fun leaveSpot() : NullResultResponse
}
\ No newline at end of file
diff --git a/data/user/src/main/java/com/umcspot/spot/user/datasourceimpl/UserDataSourceImpl.kt b/data/user/src/main/java/com/umcspot/spot/user/datasourceimpl/UserDataSourceImpl.kt
index 5f3bec5d..0bb7b78c 100644
--- a/data/user/src/main/java/com/umcspot/spot/user/datasourceimpl/UserDataSourceImpl.kt
+++ b/data/user/src/main/java/com/umcspot/spot/user/datasourceimpl/UserDataSourceImpl.kt
@@ -51,4 +51,7 @@ class UserDataSourceImpl @Inject constructor(
override suspend fun getUserPreferredCategory(): BaseResponse =
userService.getUserPreferredCategory()
+
+ override suspend fun leaveSpot(): NullResultResponse =
+ userService.leaveSpot()
}
\ No newline at end of file
diff --git a/data/user/src/main/java/com/umcspot/spot/user/repositoryimpl/UserRepositoryImpl.kt b/data/user/src/main/java/com/umcspot/spot/user/repositoryimpl/UserRepositoryImpl.kt
index dbb2c9c3..5aae05f6 100644
--- a/data/user/src/main/java/com/umcspot/spot/user/repositoryimpl/UserRepositoryImpl.kt
+++ b/data/user/src/main/java/com/umcspot/spot/user/repositoryimpl/UserRepositoryImpl.kt
@@ -3,7 +3,6 @@ package com.umcspot.spot.user.repositoryimpl
import android.content.Context
import android.util.Log
import com.umcspot.spot.common.location.LocationStore
-import com.umcspot.spot.common.location.mapRegionCodesToFullNames
import com.umcspot.spot.model.StudyTheme
import com.umcspot.spot.user.datasource.UserDataSource
import com.umcspot.spot.user.mapper.toDomain
@@ -18,7 +17,7 @@ import javax.inject.Inject
class UserRepositoryImpl @Inject constructor(
private val userDataSource: UserDataSource,
- @ApplicationContext private val appContext: Context, // @ApplicationContext 로 주입 추천
+ @ApplicationContext private val appContext: Context,
) : UserRepository {
override suspend fun getUserName(): Result =
runCatching {
@@ -87,4 +86,11 @@ class UserRepositoryImpl @Inject constructor(
}.onFailure {
Log.e("UserRepository", "getUserPreferredCategory failed", it)
}
+
+ override suspend fun leaveSpot() : Result =
+ runCatching {
+ userDataSource.leaveSpot().code
+ }.onFailure {
+ Log.e("UserRepository", "leaveSpot failed", it)
+ }
}
\ No newline at end of file
diff --git a/data/user/src/main/java/com/umcspot/spot/user/service/UserService.kt b/data/user/src/main/java/com/umcspot/spot/user/service/UserService.kt
index a2f90d61..e79d5a33 100644
--- a/data/user/src/main/java/com/umcspot/spot/user/service/UserService.kt
+++ b/data/user/src/main/java/com/umcspot/spot/user/service/UserService.kt
@@ -10,6 +10,7 @@ import com.umcspot.spot.user.dto.response.UserPreferredCategoryResponseDto
import com.umcspot.spot.user.dto.response.UserPreferredRegionResponseDto
import com.umcspot.spot.user.dto.response.UserResponseDto
import retrofit2.http.Body
+import retrofit2.http.DELETE
import retrofit2.http.GET
import retrofit2.http.POST
@@ -44,4 +45,8 @@ interface UserService {
@GET("/api/members/prefer-categories")
suspend fun getUserPreferredCategory(
): BaseResponse
+
+ @DELETE("/api/members/me")
+ suspend fun leaveSpot(
+ ): NullResultResponse
}
\ No newline at end of file
diff --git a/domain/study/src/main/java/com/umcspot/spot/study/model/StudyResult.kt b/domain/study/src/main/java/com/umcspot/spot/study/model/StudyResult.kt
index 926b0039..8b9248c8 100644
--- a/domain/study/src/main/java/com/umcspot/spot/study/model/StudyResult.kt
+++ b/domain/study/src/main/java/com/umcspot/spot/study/model/StudyResult.kt
@@ -28,6 +28,7 @@ data class StudyResult(
val likeCount: Int = 0,
val isLiked : Boolean,
val isOwner : Boolean,
+ val isAlone : Boolean,
val hitCount: Int = 0,
val profileImageUrl: ImageRef
) {
@@ -53,6 +54,7 @@ data class StudyResult(
likeCount = 10 + index * 2,
isLiked = index%2 == 0,
isOwner = index%2 == 1,
+ isAlone = index%2 == 1,
hitCount = 150 + index * 20,
profileImageUrl = ImageRef.Name("ic_study_default")
)
diff --git a/domain/user/src/main/java/com/umcspot/spot/user/model/UserPreferredCategoryResult.kt b/domain/user/src/main/java/com/umcspot/spot/user/model/UserPreferredCategoryResult.kt
index 06316941..78adc3a2 100644
--- a/domain/user/src/main/java/com/umcspot/spot/user/model/UserPreferredCategoryResult.kt
+++ b/domain/user/src/main/java/com/umcspot/spot/user/model/UserPreferredCategoryResult.kt
@@ -3,6 +3,6 @@ package com.umcspot.spot.user.model
import com.umcspot.spot.model.StudyTheme
data class UserPreferredCategoryResult(
- val categories : List,
+ val categories : List,
val totalCount: Int
)
\ No newline at end of file
diff --git a/domain/user/src/main/java/com/umcspot/spot/user/repository/UserRepository.kt b/domain/user/src/main/java/com/umcspot/spot/user/repository/UserRepository.kt
index e5553565..1bce239b 100644
--- a/domain/user/src/main/java/com/umcspot/spot/user/repository/UserRepository.kt
+++ b/domain/user/src/main/java/com/umcspot/spot/user/repository/UserRepository.kt
@@ -17,4 +17,6 @@ interface UserRepository {
suspend fun getMyPageInfo() : Result
suspend fun getUserPreferredCategory() : Result
+
+ suspend fun leaveSpot() : Result
}
\ No newline at end of file
diff --git a/feature/board/src/main/java/com/umcspot/spot/feature/board/post/content/PostContentScreen.kt b/feature/board/src/main/java/com/umcspot/spot/feature/board/post/content/PostContentScreen.kt
index 93ff71d8..dc791c37 100644
--- a/feature/board/src/main/java/com/umcspot/spot/feature/board/post/content/PostContentScreen.kt
+++ b/feature/board/src/main/java/com/umcspot/spot/feature/board/post/content/PostContentScreen.kt
@@ -259,6 +259,7 @@ fun PostContentScreen(
modalTitle = "신고 완료",
modalDes = "게시글 신고가 완료되었어요.\n쾌적한 서비스 이용을 위해 항상 노력하겠습니다.",
okButtonText = "확인",
+ noButtonText = null,
onDismiss = { showAcceptRequestDialog = false },
onClick = { showAcceptRequestDialog = false }
)
diff --git a/feature/main/src/main/java/com/umcspot/spot/main/MainActivity.kt b/feature/main/src/main/java/com/umcspot/spot/main/MainActivity.kt
index 817018a8..ee3fbcd1 100644
--- a/feature/main/src/main/java/com/umcspot/spot/main/MainActivity.kt
+++ b/feature/main/src/main/java/com/umcspot/spot/main/MainActivity.kt
@@ -23,7 +23,7 @@ class MainActivity : ComponentActivity() {
setContent {
SpotTheme {
- MainScreen()
+ MainScreen( )
}
}
}
diff --git a/feature/main/src/main/java/com/umcspot/spot/main/MainNavHost.kt b/feature/main/src/main/java/com/umcspot/spot/main/MainNavHost.kt
index 520e64eb..c7ff125d 100644
--- a/feature/main/src/main/java/com/umcspot/spot/main/MainNavHost.kt
+++ b/feature/main/src/main/java/com/umcspot/spot/main/MainNavHost.kt
@@ -23,6 +23,11 @@ import com.umcspot.spot.feature.board.post.posting.navigation.postingGraph
import com.umcspot.spot.home.navigation.homeGraph
import com.umcspot.spot.jjim.navigation.jjimGraph
import com.umcspot.spot.model.QuickMenuType
+import com.umcspot.spot.mypage.cancelMemberShip.navigation.cancelMemberShipGraph
+import com.umcspot.spot.mypage.cancelMemberShip.navigation.navigateToCancelMembership
+import com.umcspot.spot.mypage.editInterestStudy.navigation.interestStudyGraph
+import com.umcspot.spot.mypage.editInterestStudy.navigation.navigateToEditInterestStudy
+import com.umcspot.spot.mypage.main.navigation.MyPage
import com.umcspot.spot.mypage.main.navigation.mypageGraph
import com.umcspot.spot.mypage.participating.navigation.navigateToParticipatingStudy
import com.umcspot.spot.mypage.participating.navigation.participatingGraph
@@ -30,6 +35,7 @@ import com.umcspot.spot.mypage.recruiting.navigation.myRecruitingStudyGraph
import com.umcspot.spot.mypage.recruiting.navigation.navigateToMyRecruitingStudy
import com.umcspot.spot.mypage.waiting.navigation.navigateToWaitingStudy
import com.umcspot.spot.mypage.waiting.navigation.waitingStudyGraph
+import com.umcspot.spot.signup.navigation.navigateToLanding
import com.umcspot.spot.signup.navigation.signupGraph
import com.umcspot.spot.study.detail.navigation.navigateToStudyDetail
import com.umcspot.spot.study.detail.navigation.studyDetailGraph
@@ -51,7 +57,7 @@ fun MainNavHost(
modifier: Modifier = Modifier,
contentPadding: PaddingValues = PaddingValues(0.dp),
onRegisterScrollToTop: ((() -> Unit)?) -> Unit,
- onBackRequest : () -> Unit
+ onBackRequest : () -> Unit,
) {
val clearStackNavOptions = navOptions {
popUpTo(0) { inclusive = true }
@@ -113,13 +119,22 @@ fun MainNavHost(
onItemClick = { navigator.navigateToStudyDetail(it) }
)
+
+ /** MyPage **/
mypageGraph(
contentPadding = contentPadding,
onParticipatingClick = { navigator.navController.navigateToParticipatingStudy() },
onMyRecruitingClick = { navigator.navController.navigateToMyRecruitingStudy() },
onMyAppliedClick = { navigator.navController.navigateToWaitingStudy() },
- onEditInterestClick = { /*navigator.navigateToCheckList*/ },
- onEditInterestLocationClick = { }
+ onEditInterestClick = { navigator.navController.navigateToEditInterestStudy() },
+ onEditInterestLocationClick = { },
+ onCancelMemberShipClick = { navigator.navController.navigateToCancelMembership() },
+ onLogoutClick = {
+ // 1) 로그아웃 처리(데이터 삭제) 트리거
+
+ // 2) Landing으로 이동하면서 스택 클리어
+ navigator.navController.navigateToLanding(clearStackNavOptions)
+ }
)
participatingGraph(
@@ -144,6 +159,32 @@ fun MainNavHost(
moveToRecruitingStudy = { navigator.navigateToRecruitingStudy() },
)
+ interestStudyGraph(
+ contentPadding = contentPadding,
+ moveToMyInterestStudy = { navigator.navController.navigateToPreferCategoryStudy(
+ navOptions {
+ popUpTo { inclusive = false }
+ launchSingleTop = true
+ restoreState = false
+ }
+ ) },
+ moveToMyPage = { navigator.navController.popBackStack() }
+ )
+
+ cancelMemberShipGraph(
+ contentPadding = contentPadding,
+ successCancelMemberShip = { navigator.navController.navigateToLanding(clearStackNavOptions) },
+ moveToParticipatingStudy = { navigator.navController.navigateToParticipatingStudy(
+ navOptions {
+ popUpTo { inclusive = false }
+ launchSingleTop = true
+ restoreState = false
+ }
+ ) }
+ )
+ /************/
+
+
recruitingStudyGraph(
contentPadding = contentPadding,
onRegisterScrollToTop = onRegisterScrollToTop,
diff --git a/feature/main/src/main/java/com/umcspot/spot/main/MainNavigator.kt b/feature/main/src/main/java/com/umcspot/spot/main/MainNavigator.kt
index 0153a8ed..6df57ed0 100644
--- a/feature/main/src/main/java/com/umcspot/spot/main/MainNavigator.kt
+++ b/feature/main/src/main/java/com/umcspot/spot/main/MainNavigator.kt
@@ -22,6 +22,8 @@ import com.umcspot.spot.home.navigation.Home
import com.umcspot.spot.home.navigation.navigateToHome
import com.umcspot.spot.jjim.navigation.JJim
import com.umcspot.spot.jjim.navigation.navigateToJJim
+import com.umcspot.spot.mypage.cancelMemberShip.navigation.CancelMemberShip
+import com.umcspot.spot.mypage.editInterestStudy.navigation.EditInterest
import com.umcspot.spot.mypage.main.navigation.MyPage
import com.umcspot.spot.mypage.main.navigation.navigateToMyPage
import com.umcspot.spot.mypage.participating.navigation.ParticipatingStudy
@@ -103,7 +105,7 @@ class MainNavigator(
@Composable
fun showBackTopBar(): Boolean = inAnyGraph(Alert::class, RecruitingFilter::class, PreferLocationFilter::class, PreferCategoryFilter::class,
SignUp::class, CheckList::class, Posting::class, BoardList::class, JJim::class, MyPage::class,
- ParticipatingStudy::class, MyRecruitingStudy::class, WaitingStudy::class
+ ParticipatingStudy::class, MyRecruitingStudy::class, WaitingStudy::class, EditInterest::class, CancelMemberShip::class
) || inAnyGraphRoutes(POST_CONTENT_ROUTE)
@Composable
diff --git a/feature/main/src/main/java/com/umcspot/spot/main/MainScreen.kt b/feature/main/src/main/java/com/umcspot/spot/main/MainScreen.kt
index 055fd6a0..55e1846e 100644
--- a/feature/main/src/main/java/com/umcspot/spot/main/MainScreen.kt
+++ b/feature/main/src/main/java/com/umcspot/spot/main/MainScreen.kt
@@ -35,6 +35,9 @@ import com.umcspot.spot.feature.board.post.posting.navigation.navigateToPostingN
import com.umcspot.spot.home.navigation.Home
import com.umcspot.spot.jjim.navigation.JJim
import com.umcspot.spot.main.component.MainBottomBar
+import com.umcspot.spot.mypage.cancelMemberShip.CancelMemberShipScreen
+import com.umcspot.spot.mypage.cancelMemberShip.navigation.CancelMemberShip
+import com.umcspot.spot.mypage.editInterestStudy.navigation.EditInterest
import com.umcspot.spot.mypage.main.navigation.MyPage
import com.umcspot.spot.mypage.participating.navigation.ParticipatingStudy
import com.umcspot.spot.mypage.recruiting.navigation.MyRecruitingStudy
@@ -50,7 +53,7 @@ import kotlinx.collections.immutable.toImmutableList
@Composable
fun MainScreen(
- navigator: MainNavigator = rememberMainNavigator()
+ navigator: MainNavigator = rememberMainNavigator(),
) {
val navController = navigator.navController
val backStackEntry by navController.currentBackStackEntryAsState()
@@ -81,6 +84,8 @@ fun MainScreen(
dest?.hasRoute(ParticipatingStudy::class) == true -> "참여 중인 스터디"
dest?.hasRoute(MyRecruitingStudy::class) == true -> "모집 중인 스터디"
dest?.hasRoute(WaitingStudy::class) == true -> "대기 중인 스터디"
+ dest?.hasRoute(EditInterest::class) == true -> "관심 분야"
+ dest?.hasRoute(CancelMemberShip::class) == true -> "회원 탈퇴"
dest?.routeMatches(POST_CONTENT_ROUTE) == true -> "스터디 파트너들의 이야기"
else -> ""
}
@@ -146,7 +151,7 @@ fun MainScreen(
.consumeWindowInsets(innerPadding),
contentPadding = innerPadding,
onRegisterScrollToTop = { handler -> scrollToTop = handler },
- onBackRequest = { showBackRequestDialog = true }
+ onBackRequest = { showBackRequestDialog = true },
)
}
diff --git a/feature/mypage/src/main/java/com/umcspot/spot/mypage/cancelMemberShip/CancelMemberShipScreen.kt b/feature/mypage/src/main/java/com/umcspot/spot/mypage/cancelMemberShip/CancelMemberShipScreen.kt
new file mode 100644
index 00000000..dfe41695
--- /dev/null
+++ b/feature/mypage/src/main/java/com/umcspot/spot/mypage/cancelMemberShip/CancelMemberShipScreen.kt
@@ -0,0 +1,196 @@
+package com.umcspot.spot.mypage.cancelMemberShip
+
+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.Spacer
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.width
+import androidx.compose.material3.HorizontalDivider
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.painterResource
+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.umcspot.spot.designsystem.R
+import com.umcspot.spot.designsystem.component.button.TextButton
+import com.umcspot.spot.designsystem.component.button.TextButtonState
+import com.umcspot.spot.designsystem.component.modal.RejectDialog
+import com.umcspot.spot.designsystem.shapes.SpotShapes
+import com.umcspot.spot.designsystem.theme.G300
+import com.umcspot.spot.designsystem.theme.G400
+import com.umcspot.spot.designsystem.theme.R500
+import com.umcspot.spot.designsystem.theme.SpotTheme
+import com.umcspot.spot.ui.extension.screenHeightDp
+import com.umcspot.spot.ui.extension.screenWidthDp
+
+@Composable
+fun CancelMemberShipScreen(
+ contentPadding : PaddingValues,
+ successCancelMemberShip: () -> Unit,
+ moveToParticipatingStudy: () -> Unit,
+ viewmodel : CancelMemberShipViewModel = hiltViewModel()
+) {
+ var showDialog by remember { mutableStateOf(false) }
+ var showFailDialog by remember { mutableStateOf(false) }
+ var showSuccessDialog by remember { mutableStateOf(false) }
+ val status by viewmodel.leaveStatus.collectAsStateWithLifecycle()
+
+ LaunchedEffect(status) {
+ when(status) {
+ "MEMBER4006" -> { showFailDialog = true }
+ "MEMBER200" -> { showSuccessDialog = true }
+ }
+ }
+
+ Column(
+ modifier = Modifier
+ .background(SpotTheme.colors.white)
+ .padding(
+ top = contentPadding.calculateTopPadding(),
+ bottom = contentPadding.calculateBottomPadding()
+ )
+ .padding(horizontal = screenWidthDp(17.dp), vertical = screenHeightDp(18.dp)),
+ horizontalAlignment = Alignment.Start,
+ verticalArrangement = Arrangement.Top
+ ) {
+ Text(text = "SPOT 탈퇴 전 확인하세요.", style = SpotTheme.typography.h3)
+
+ Spacer(modifier = Modifier.height(screenHeightDp(10.dp)))
+
+ Text(text = "탈퇴하시면 아래 정보들은 모두 파기되며 모든 데이터들은", style = SpotTheme.typography.regular_500)
+
+ Spacer(modifier = Modifier.height(screenHeightDp(4.dp)))
+
+ Row {
+ Text(text = "복구가", style = SpotTheme.typography.regular_500)
+
+ Spacer(modifier = Modifier.width(screenWidthDp(8.dp)))
+
+ Text(
+ text = "불가능",
+ style = SpotTheme.typography.regular_500,
+ color = SpotTheme.colors.R500
+ )
+ Text(text = "합니다.", style = SpotTheme.typography.regular_500)
+ }
+
+ Spacer(modifier = Modifier.height(screenHeightDp(40.dp)))
+
+ HorizontalDivider(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(horizontal = screenWidthDp(4.dp)),
+ color = SpotTheme.colors.G300,
+ thickness = 1.dp,
+ )
+
+ Spacer(modifier = Modifier.height(screenHeightDp(40.dp)))
+
+ Text(text = "회원 정보", style = SpotTheme.typography.large_500)
+
+ Spacer(modifier = Modifier.height(screenHeightDp(7.dp)))
+
+ Text(text = "로그인 이메일, 성명, 생년월일 정보가 모두 삭제됩니다.", style = SpotTheme.typography.regular_500)
+
+ Spacer(modifier = Modifier.height(screenHeightDp(40.dp)))
+
+ Text(text = "스터디 정보", style = SpotTheme.typography.large_500)
+
+ Spacer(modifier = Modifier.height(screenHeightDp(7.dp)))
+
+ Text(text = "진행 중 스터디, 모집 중 스터디, 스터디 찜 정보, 모든 게시글, 댓글, 사진,", style = SpotTheme.typography.regular_500)
+
+ Spacer(modifier = Modifier.height(screenHeightDp(4.dp)))
+
+ Text(text = "개인 관심사/관심지역 정보 등이 모두 삭제됩니다.", style = SpotTheme.typography.regular_500)
+
+ Spacer(modifier = Modifier.weight(1f))
+
+ TextButton(
+ modifier = Modifier
+ .width(screenWidthDp(326.dp))
+ .height(screenHeightDp(47.dp)),
+ text = "탈퇴하기",
+ style = SpotTheme.typography.h3,
+ state = TextButtonState.R500State,
+ shape = SpotShapes.Soft,
+ onClick = { showDialog = true }
+ )
+
+ RejectDialog(
+ visible = showDialog,
+ painter = painterResource(R.drawable.cancel_membership),
+ painterTint = SpotTheme.colors.G400,
+ modalTitle = "정말 탈퇴할까요?",
+ modalDes = null,
+ okButtonText = "탈퇴",
+ noButtonText = "취소",
+ onDismiss = { showDialog = false },
+ onClick = {
+ viewmodel.leaveSpot()
+ showDialog = false
+ },
+ onCancel = { showDialog = false }
+ )
+
+ RejectDialog(
+ visible = showFailDialog,
+ painter = painterResource(R.drawable.error),
+ painterTint = SpotTheme.colors.R500,
+ modalTitle = "호스트로 운영중인 스터디가 있어요.",
+ modalDes = "호스트로 운영중인 스터디를 먼저 나가야\n스팟 서비스를 탈퇴할 수 있어요.",
+ okButtonText = "스터디 나가기",
+ noButtonText = "취소",
+ onDismiss = { showFailDialog = false },
+ onClick = {
+ showFailDialog = false
+ moveToParticipatingStudy()
+ },
+ onCancel = { showFailDialog = false }
+ )
+
+ RejectDialog(
+ visible = showSuccessDialog,
+ painter = painterResource(R.drawable.success_default),
+ painterTint = SpotTheme.colors.R500,
+ modalTitle = "탈퇴 처리 완료",
+ modalDes = null,
+ okButtonText = "확인",
+ noButtonText = null,
+ onDismiss = {
+ showSuccessDialog = false
+ successCancelMemberShip()
+ },
+ onClick = {
+ showSuccessDialog = false
+ successCancelMemberShip()
+ },
+ )
+ }
+}
+
+@Preview(showBackground = true)
+@Composable
+private fun CancelMemberShipScreenPreview() {
+ SpotTheme {
+ CancelMemberShipScreen(
+ contentPadding = PaddingValues(0.dp),
+ successCancelMemberShip = {},
+ moveToParticipatingStudy = {}
+ )
+ }
+}
\ No newline at end of file
diff --git a/feature/mypage/src/main/java/com/umcspot/spot/mypage/cancelMemberShip/CancelMemberShipViewModel.kt b/feature/mypage/src/main/java/com/umcspot/spot/mypage/cancelMemberShip/CancelMemberShipViewModel.kt
new file mode 100644
index 00000000..906cbfd3
--- /dev/null
+++ b/feature/mypage/src/main/java/com/umcspot/spot/mypage/cancelMemberShip/CancelMemberShipViewModel.kt
@@ -0,0 +1,34 @@
+package com.umcspot.spot.mypage.cancelMemberShip
+
+import android.util.Log
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import com.umcspot.spot.user.repository.UserRepository
+import dagger.hilt.android.lifecycle.HiltViewModel
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.launch
+import javax.inject.Inject
+
+@HiltViewModel
+class CancelMemberShipViewModel @Inject constructor(
+ private val userRepository: UserRepository
+) : ViewModel() {
+ private val _leaveStatus = MutableStateFlow("")
+ val leaveStatus : StateFlow = _leaveStatus
+
+ fun leaveSpot() {
+ Log.d("CancelMemberShipVM", "leaveSpot CALLED")
+ viewModelScope.launch {
+ userRepository.leaveSpot()
+ .onSuccess { status ->
+ Log.d("CancelMemberShipVM", "leaveSpot success status=$status")
+ _leaveStatus.value = status
+ }
+ .onFailure { e ->
+ Log.e("CancelMemberShipVM", "leaveSpot failed", e)
+ }
+ }
+ }
+}
+
diff --git a/feature/mypage/src/main/java/com/umcspot/spot/mypage/cancelMemberShip/navigation/CancelMemberShipNavigation.kt b/feature/mypage/src/main/java/com/umcspot/spot/mypage/cancelMemberShip/navigation/CancelMemberShipNavigation.kt
new file mode 100644
index 00000000..e605e8b8
--- /dev/null
+++ b/feature/mypage/src/main/java/com/umcspot/spot/mypage/cancelMemberShip/navigation/CancelMemberShipNavigation.kt
@@ -0,0 +1,31 @@
+package com.umcspot.spot.mypage.cancelMemberShip.navigation
+
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.navigation.NavController
+import androidx.navigation.NavGraphBuilder
+import androidx.navigation.NavOptions
+import androidx.navigation.compose.composable
+import com.umcspot.spot.mypage.cancelMemberShip.CancelMemberShipScreen
+import com.umcspot.spot.navigation.Route
+import kotlinx.serialization.Serializable
+
+fun NavController.navigateToCancelMembership(navOptions: NavOptions? = null) {
+ navigate(CancelMemberShip, navOptions)
+}
+
+fun NavGraphBuilder.cancelMemberShipGraph(
+ contentPadding : PaddingValues,
+ successCancelMemberShip: () -> Unit,
+ moveToParticipatingStudy: () -> Unit,
+) {
+ composable {
+ CancelMemberShipScreen(
+ contentPadding = contentPadding,
+ successCancelMemberShip = successCancelMemberShip,
+ moveToParticipatingStudy = moveToParticipatingStudy
+ )
+ }
+}
+
+@Serializable
+data object CancelMemberShip : Route
\ No newline at end of file
diff --git a/feature/mypage/src/main/java/com/umcspot/spot/mypage/editInterestStudy/EditInterestStudyScreen.kt b/feature/mypage/src/main/java/com/umcspot/spot/mypage/editInterestStudy/EditInterestStudyScreen.kt
new file mode 100644
index 00000000..23fdcdbe
--- /dev/null
+++ b/feature/mypage/src/main/java/com/umcspot/spot/mypage/editInterestStudy/EditInterestStudyScreen.kt
@@ -0,0 +1,156 @@
+package com.umcspot.spot.mypage.editInterestStudy
+
+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.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.width
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+import androidx.hilt.navigation.compose.hiltViewModel
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import com.umcspot.spot.designsystem.component.button.TextButton
+import com.umcspot.spot.designsystem.component.button.TextButtonState
+import com.umcspot.spot.designsystem.component.modal.AcceptDialog
+import com.umcspot.spot.designsystem.component.study.section.ActivityThemeSection
+import com.umcspot.spot.designsystem.shapes.SpotShapes
+import com.umcspot.spot.designsystem.theme.SpotTheme
+import com.umcspot.spot.ui.extension.screenHeightDp
+import com.umcspot.spot.ui.extension.screenWidthDp
+
+@Composable
+fun EditInterestStudyScreen(
+ contentPadding : PaddingValues,
+ moveToMyInterestStudy: () -> Unit,
+ moveToMyPage: () -> Unit,
+ viewmodel : EditInterestStudyViewModel = hiltViewModel()
+) {
+ var showDialog by remember { mutableStateOf(false) }
+ var editMode by remember { mutableStateOf(false) }
+ val selectedThemes by viewmodel.preferCategories.collectAsStateWithLifecycle()
+ var draftThemes by remember { mutableStateOf(selectedThemes) }
+
+ val topPad = contentPadding.calculateTopPadding()
+ val bottomPad = contentPadding.calculateBottomPadding()
+
+ LaunchedEffect(Unit) {
+ viewmodel.loadPreferCategories()
+ }
+
+ LaunchedEffect(selectedThemes) {
+ if (!editMode) draftThemes = selectedThemes
+ }
+
+ Column(
+ modifier = Modifier
+ .fillMaxSize()
+ .background(SpotTheme.colors.white)
+ .padding(top = topPad, bottom = bottomPad)
+ .padding(horizontal = screenWidthDp(17.dp), vertical = screenHeightDp(30.dp))
+ ) {
+ Spacer(Modifier.height(screenHeightDp(68.dp)))
+
+ Text(
+ text = "내가 원하는 스터디를 선택해주세요!",
+ style = SpotTheme.typography.h3,
+ color = SpotTheme.colors.black
+ )
+
+ Spacer(Modifier.height(screenHeightDp(40.dp)))
+
+ Column(
+ modifier = Modifier
+ .weight(1f)
+ ) {
+ ActivityThemeSection(
+ selectedThemes = if (editMode) draftThemes else selectedThemes,
+ onSelect = { theme ->
+ if (!editMode) return@ActivityThemeSection
+
+ draftThemes =
+ if (draftThemes.contains(theme)) draftThemes - theme else draftThemes + theme
+ },
+ modifier = Modifier.fillMaxWidth(),
+ maxSelection = 10,
+ )
+ }
+
+ if(editMode) {
+ Row(
+ modifier = Modifier.fillMaxWidth(),
+ horizontalArrangement = Arrangement.SpaceBetween
+ ) {
+ TextButton(
+ modifier = Modifier
+ .width(screenWidthDp(156.dp))
+ .height(screenHeightDp(47.dp)),
+ text = "취소",
+ style = SpotTheme.typography.h3,
+ onClick = {
+ draftThemes = selectedThemes
+ editMode = false
+ },
+ shape = SpotShapes.Soft,
+ state = TextButtonState.G500State,
+ )
+
+ TextButton(
+ modifier = Modifier
+ .width(screenWidthDp(156.dp))
+ .height(screenHeightDp(47.dp)),
+ text = "완료",
+ style = SpotTheme.typography.h3,
+ onClick = {
+ viewmodel.updatePreferCategories(draftThemes)
+ showDialog = true
+ },
+ shape = SpotShapes.Soft,
+ state = TextButtonState.B500State,
+ )
+ }
+ } else {
+ TextButton(
+ modifier = Modifier
+ .width(screenWidthDp(326.dp))
+ .height(screenHeightDp(47.dp)),
+ text = "수정",
+ style = SpotTheme.typography.h3,
+ onClick = {
+ draftThemes = selectedThemes
+ editMode = true
+ },
+ shape = SpotShapes.Soft,
+ state = TextButtonState.B500State,
+ )
+ }
+
+ AcceptDialog(
+ visible = showDialog,
+ modalTitle = "",
+ modalDes = "수정이 완료되었어요.\n새로운 관심 분야에 맞는 스터디를 확인해보세요.",
+ okButtonText = "내 관심 스터디 보기",
+ noButtonText = null,
+ onClick = {
+ showDialog = false
+ moveToMyInterestStudy()
+ },
+ onDismiss = {
+ showDialog = false
+ moveToMyPage()
+ }
+ )
+ }
+}
\ No newline at end of file
diff --git a/feature/mypage/src/main/java/com/umcspot/spot/mypage/editInterestStudy/EditInterestStudyViewModel.kt b/feature/mypage/src/main/java/com/umcspot/spot/mypage/editInterestStudy/EditInterestStudyViewModel.kt
new file mode 100644
index 00000000..9726f818
--- /dev/null
+++ b/feature/mypage/src/main/java/com/umcspot/spot/mypage/editInterestStudy/EditInterestStudyViewModel.kt
@@ -0,0 +1,47 @@
+package com.umcspot.spot.mypage.editInterestStudy
+
+import android.util.Log
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import com.umcspot.spot.model.StudyTheme
+import com.umcspot.spot.study.model.Study
+import com.umcspot.spot.user.repository.UserRepository
+import dagger.hilt.android.lifecycle.HiltViewModel
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.launch
+import javax.inject.Inject
+
+@HiltViewModel
+class EditInterestStudyViewModel @Inject constructor(
+ private val userRepository: UserRepository
+) : ViewModel() {
+ private val _preferCategories = MutableStateFlow>(emptyList())
+ val preferCategories : StateFlow> = _preferCategories.asStateFlow()
+
+ fun loadPreferCategories() {
+ viewModelScope.launch {
+ userRepository.getUserPreferredCategory()
+ .onSuccess {
+ _preferCategories.value = it.categories
+ }
+ .onFailure {
+ Log.e("EditInterestStudyViewModel", "loadPreferCategories: ${it.message}")
+ }
+ }
+ }
+
+ fun updatePreferCategories(categories: List) {
+ viewModelScope.launch {
+ userRepository.setUserTheme(categories)
+ .onSuccess {
+ _preferCategories.value = categories
+ }
+ .onFailure {
+ Log.e("EditInterestStudyViewModel", "updatePreferCategories: ${it.message}")
+ }
+ }
+ }
+}
+
diff --git a/feature/mypage/src/main/java/com/umcspot/spot/mypage/editInterestStudy/navigation/EditInterestStudyNavigation.kt b/feature/mypage/src/main/java/com/umcspot/spot/mypage/editInterestStudy/navigation/EditInterestStudyNavigation.kt
new file mode 100644
index 00000000..d236c75e
--- /dev/null
+++ b/feature/mypage/src/main/java/com/umcspot/spot/mypage/editInterestStudy/navigation/EditInterestStudyNavigation.kt
@@ -0,0 +1,31 @@
+package com.umcspot.spot.mypage.editInterestStudy.navigation
+
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.navigation.NavController
+import androidx.navigation.NavGraphBuilder
+import androidx.navigation.NavOptions
+import androidx.navigation.compose.composable
+import com.umcspot.spot.mypage.editInterestStudy.EditInterestStudyScreen
+import com.umcspot.spot.navigation.MainTabRoute
+import kotlinx.serialization.Serializable
+
+fun NavController.navigateToEditInterestStudy(navOptions: NavOptions? = null) {
+ navigate(EditInterest, navOptions)
+}
+
+fun NavGraphBuilder.interestStudyGraph(
+ contentPadding : PaddingValues,
+ moveToMyInterestStudy: () -> Unit,
+ moveToMyPage: () -> Unit
+) {
+ composable {
+ EditInterestStudyScreen(
+ contentPadding = contentPadding,
+ moveToMyInterestStudy = moveToMyInterestStudy,
+ moveToMyPage = moveToMyPage
+ )
+ }
+}
+
+@Serializable
+data object EditInterest : MainTabRoute
\ No newline at end of file
diff --git a/feature/mypage/src/main/java/com/umcspot/spot/mypage/main/MyPageScreen.kt b/feature/mypage/src/main/java/com/umcspot/spot/mypage/main/MyPageScreen.kt
index 6c1ff461..4cebc772 100644
--- a/feature/mypage/src/main/java/com/umcspot/spot/mypage/main/MyPageScreen.kt
+++ b/feature/mypage/src/main/java/com/umcspot/spot/mypage/main/MyPageScreen.kt
@@ -1,6 +1,5 @@
package com.umcspot.spot.mypage.main
-import android.util.Log
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
@@ -23,7 +22,9 @@ import androidx.compose.material3.VerticalDivider
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
@@ -40,6 +41,7 @@ import com.umcspot.spot.designsystem.component.ProfileImage
import com.umcspot.spot.designsystem.component.SpotSpinner
import com.umcspot.spot.designsystem.component.button.BlankButton
import com.umcspot.spot.designsystem.component.button.ImageButtonState
+import com.umcspot.spot.designsystem.component.modal.AcceptDialog
import com.umcspot.spot.designsystem.shapes.ShapeBox
import com.umcspot.spot.designsystem.shapes.SpotShapes
import com.umcspot.spot.designsystem.theme.B100
@@ -63,11 +65,12 @@ fun MyPageScreen(
onMyAppliedClick : () -> Unit,
onEditInterestClick : () -> Unit,
onEditInterestLocationClick : () -> Unit,
+ onCancelMemberShipClick: () -> Unit,
+ onLogoutClick:() -> Unit,
viewmodel : MyPageViewModel = hiltViewModel()
) {
val uiState by viewmodel.uiState.collectAsStateWithLifecycle()
-
LaunchedEffect(Unit) {
viewmodel.load()
}
@@ -85,7 +88,9 @@ fun MyPageScreen(
onMyRecruitingClick = onMyRecruitingClick,
onMyAppliedClick = onMyAppliedClick,
onEditInterestClick = onEditInterestClick,
- onEditInterestLocationClick = onEditInterestLocationClick
+ onEditInterestLocationClick = onEditInterestLocationClick,
+ onCancelMemberShipClick = onCancelMemberShipClick,
+ onLogoutClick = onLogoutClick
)
}
@@ -101,282 +106,326 @@ fun MyPageScreenContent(
onMyAppliedClick: () -> Unit,
onEditInterestClick: () -> Unit,
onEditInterestLocationClick: () -> Unit,
+ onCancelMemberShipClick: () -> Unit,
+ onLogoutClick: () -> Unit
) {
- LazyColumn(
- modifier = modifier
- .padding(top = screenHeightDp(18.dp))
- .padding(horizontal = screenWidthDp(17.dp)),
- contentPadding = PaddingValues(bottom = screenHeightDp(24.dp))
+ var logout by remember { mutableStateOf(false) }
+ var successLogout by remember { mutableStateOf(false) }
+
+ Box(
+ modifier = Modifier.fillMaxSize()
) {
- item {
- when (memberInfo) {
- is UiState.Loading, is UiState.Empty, is UiState.Failure -> {
- Box(
- modifier = Modifier
- .fillMaxWidth()
- .wrapContentHeight(),
- contentAlignment = Alignment.Center
- ) {
- SpotSpinner()
+ LazyColumn(
+ modifier = modifier
+ .padding(top = screenHeightDp(18.dp))
+ .padding(horizontal = screenWidthDp(17.dp)),
+ contentPadding = PaddingValues(bottom = screenHeightDp(24.dp))
+ ) {
+ item {
+ when (memberInfo) {
+ is UiState.Loading, is UiState.Empty, is UiState.Failure -> {
+ Box(
+ modifier = Modifier
+ .fillMaxWidth()
+ .wrapContentHeight(),
+ contentAlignment = Alignment.Center
+ ) {
+ SpotSpinner()
+ }
+
+ Spacer(modifier = Modifier.height(screenHeightDp(20.dp)))
}
- Spacer(modifier = Modifier.height(screenHeightDp(20.dp)))
- }
-
- is UiState.Success -> {
- val data = memberInfo.data
+ is UiState.Success -> {
+ val data = memberInfo.data
- UserProfile(
- nickName = data.nickname,
- profileImageUrl = data.profileImageUrl
- )
+ UserProfile(
+ nickName = data.nickname,
+ profileImageUrl = data.profileImageUrl
+ )
- Spacer(modifier = Modifier.height(screenHeightDp(20.dp)))
+ Spacer(modifier = Modifier.height(screenHeightDp(20.dp)))
+ }
}
}
- }
- item {
- when(memberInfo) {
- is UiState.Loading, is UiState.Empty, is UiState.Failure -> {
- Box(
- modifier = Modifier
- .fillMaxWidth()
- .wrapContentHeight(),
- contentAlignment = Alignment.Center
- ) {
- SpotSpinner()
+ item {
+ when(memberInfo) {
+ is UiState.Loading, is UiState.Empty, is UiState.Failure -> {
+ Box(
+ modifier = Modifier
+ .fillMaxWidth()
+ .wrapContentHeight(),
+ contentAlignment = Alignment.Center
+ ) {
+ SpotSpinner()
+ }
+
+ Spacer(modifier = Modifier.height(screenHeightDp(20.dp)))
}
- Spacer(modifier = Modifier.height(screenHeightDp(20.dp)))
- }
-
- is UiState.Success -> {
- val data = memberInfo.data
+ is UiState.Success -> {
+ val data = memberInfo.data
- StudyInfoFrame(
- participatingStudyCount = data.participateCount,
- recruitingStudyCount = data.recruitingCount,
- appliedStudyCount = data.appliedCount,
- onParticipatingClick = onParticipatingClick,
- onRecruitingClick = onMyRecruitingClick,
- onAppliedClick = onMyAppliedClick
- )
+ StudyInfoFrame(
+ participatingStudyCount = data.participateCount,
+ recruitingStudyCount = data.recruitingCount,
+ appliedStudyCount = data.appliedCount,
+ onParticipatingClick = onParticipatingClick,
+ onRecruitingClick = onMyRecruitingClick,
+ onAppliedClick = onMyAppliedClick
+ )
- Spacer(modifier = Modifier.height(screenHeightDp(20.dp)))
+ Spacer(modifier = Modifier.height(screenHeightDp(20.dp)))
+ }
}
}
- }
- item {
- when(preferCategory) {
- is UiState.Loading, is UiState.Empty, is UiState.Failure -> {
- Box(
- modifier = Modifier
- .fillMaxWidth()
- .wrapContentHeight(),
- contentAlignment = Alignment.Center
- ) {
- SpotSpinner()
- }
-
- Spacer(modifier = Modifier.height(screenHeightDp(20.dp)))
- }
- is UiState.Success -> {
- val data = preferCategory.data
-
- InterestedInfo(
- title = "관심 분야",
- icon = painterResource(id = R.drawable.search_prefer),
- interest = data,
- onClick = {}
- )
-
- Spacer(modifier = Modifier.height(screenHeightDp(7.dp)))
+ item {
+ when(preferCategory) {
+ is UiState.Loading, is UiState.Empty, is UiState.Failure -> {
+ Box(
+ modifier = Modifier
+ .fillMaxWidth()
+ .wrapContentHeight(),
+ contentAlignment = Alignment.Center
+ ) {
+ SpotSpinner()
+ }
- HorizontalDivider(
- color = SpotTheme.colors.G300,
- thickness = 1.dp,
- modifier = Modifier
- .fillMaxWidth()
- .padding(horizontal = screenWidthDp(4.dp))
- )
+ Spacer(modifier = Modifier.height(screenHeightDp(20.dp)))
+ }
+ is UiState.Success -> {
+ val data = preferCategory.data
+
+ InterestedInfo(
+ title = "관심 분야",
+ icon = painterResource(id = R.drawable.search_prefer),
+ interest = data,
+ onClick = onEditInterestClick
+ )
+
+ Spacer(modifier = Modifier.height(screenHeightDp(7.dp)))
+
+ HorizontalDivider(
+ color = SpotTheme.colors.G300,
+ thickness = 1.dp,
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(horizontal = screenWidthDp(4.dp))
+ )
+ }
}
}
- }
- item {
- when(preferRegion) {
- is UiState.Loading, is UiState.Empty, is UiState.Failure -> {
- Box(
- modifier = Modifier
- .fillMaxWidth()
- .wrapContentHeight(),
- contentAlignment = Alignment.Center
- ) {
- SpotSpinner()
+ item {
+ when(preferRegion) {
+ is UiState.Loading, is UiState.Empty, is UiState.Failure -> {
+ Box(
+ modifier = Modifier
+ .fillMaxWidth()
+ .wrapContentHeight(),
+ contentAlignment = Alignment.Center
+ ) {
+ SpotSpinner()
+ }
+
+ Spacer(modifier = Modifier.height(screenHeightDp(20.dp)))
}
- Spacer(modifier = Modifier.height(screenHeightDp(20.dp)))
- }
+ is UiState.Success -> {
+ val data = preferRegion.data
- is UiState.Success -> {
- val data = preferRegion.data
+ Spacer(modifier = Modifier.height(screenHeightDp(7.dp)))
- Spacer(modifier = Modifier.height(screenHeightDp(7.dp)))
-
- InterestedInfo(
- title = "관심 지역",
- icon = painterResource(id = R.drawable.location_outline),
- interest = data,
- onClick = {}
- )
+ InterestedInfo(
+ title = "관심 지역",
+ icon = painterResource(id = R.drawable.location_outline),
+ interest = data,
+ onClick = onEditInterestLocationClick
+ )
- Spacer(modifier = Modifier.height(screenHeightDp(7.dp)))
+ Spacer(modifier = Modifier.height(screenHeightDp(7.dp)))
- HorizontalDivider(
- color = SpotTheme.colors.G300,
- thickness = 1.dp,
- modifier = Modifier
- .fillMaxWidth()
- .padding(horizontal = screenWidthDp(4.dp))
- )
+ HorizontalDivider(
+ color = SpotTheme.colors.G300,
+ thickness = 1.dp,
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(horizontal = screenWidthDp(4.dp))
+ )
+ }
}
}
- }
- item {
- when(memberInfo) {
- is UiState.Loading, is UiState.Empty, is UiState.Failure -> {
- Box(
- modifier = Modifier
- .fillMaxWidth()
- .wrapContentHeight(),
- contentAlignment = Alignment.Center
- ) {
- SpotSpinner()
- }
+ item {
+ when(memberInfo) {
+ is UiState.Loading, is UiState.Empty, is UiState.Failure -> {
+ Box(
+ modifier = Modifier
+ .fillMaxWidth()
+ .wrapContentHeight(),
+ contentAlignment = Alignment.Center
+ ) {
+ SpotSpinner()
+ }
- Spacer(modifier = Modifier.height(screenHeightDp(20.dp)))
- }
+ Spacer(modifier = Modifier.height(screenHeightDp(20.dp)))
+ }
- is UiState.Success -> {
- val data = memberInfo.data
+ is UiState.Success -> {
+ val data = memberInfo.data
- Spacer(modifier = Modifier.height(screenHeightDp(13.dp)))
+ Spacer(modifier = Modifier.height(screenHeightDp(13.dp)))
- LoginType(type = data.loginType)
+ LoginType(type = data.loginType)
- EmailInfo(email = data.email)
+ EmailInfo(email = data.email)
- Spacer(modifier = Modifier.height(screenHeightDp(13.dp)))
+ Spacer(modifier = Modifier.height(screenHeightDp(13.dp)))
- HorizontalDivider(
- color = SpotTheme.colors.G300,
- thickness = 1.dp,
- modifier = Modifier
- .fillMaxWidth()
- .padding(horizontal = screenWidthDp(4.dp))
- )
+ HorizontalDivider(
+ color = SpotTheme.colors.G300,
+ thickness = 1.dp,
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(horizontal = screenWidthDp(4.dp))
+ )
+ }
}
}
- }
- item {
- Spacer(modifier = Modifier.height(screenHeightDp(13.dp)))
+ item {
+ Spacer(modifier = Modifier.height(screenHeightDp(13.dp)))
- TermSection(
- onCommunityRuleClick = {},
- onRestrictionHistoryClick = {},
- onPrivacyPolicyClick = {},
- onTermsOfServiceClick = {}
- )
+ TermSection(
+ onCommunityRuleClick = {},
+ onRestrictionHistoryClick = {},
+ onPrivacyPolicyClick = {},
+ onTermsOfServiceClick = {}
+ )
- Spacer(modifier = Modifier.height(screenHeightDp(13.dp)))
- HorizontalDivider(
- color = SpotTheme.colors.G300,
- thickness = 1.dp,
- modifier = Modifier
- .fillMaxWidth()
- .padding(horizontal = screenWidthDp(4.dp))
- )
- }
+ Spacer(modifier = Modifier.height(screenHeightDp(13.dp)))
+ HorizontalDivider(
+ color = SpotTheme.colors.G300,
+ thickness = 1.dp,
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(horizontal = screenWidthDp(4.dp))
+ )
+ }
- item {
- when(appVersion) {
- is UiState.Loading, is UiState.Empty, is UiState.Failure -> {
- Box(
- modifier = Modifier
- .fillMaxWidth()
- .wrapContentHeight(),
- contentAlignment = Alignment.Center
- ) {
- SpotSpinner()
+ item {
+ when(appVersion) {
+ is UiState.Loading, is UiState.Empty, is UiState.Failure -> {
+ Box(
+ modifier = Modifier
+ .fillMaxWidth()
+ .wrapContentHeight(),
+ contentAlignment = Alignment.Center
+ ) {
+ SpotSpinner()
+ }
+
+ Spacer(modifier = Modifier.height(screenHeightDp(20.dp)))
}
- Spacer(modifier = Modifier.height(screenHeightDp(20.dp)))
- }
+ is UiState.Success -> {
+ val version = appVersion.data
- is UiState.Success -> {
- val version = appVersion.data
+ Spacer(modifier = Modifier.height(screenHeightDp(13.dp)))
- Spacer(modifier = Modifier.height(screenHeightDp(13.dp)))
+ AppVersion(appVersion = version)
- AppVersion(appVersion = version)
-
- Spacer(modifier = Modifier.height(screenHeightDp(13.dp)))
- HorizontalDivider(
- color = SpotTheme.colors.G300,
- thickness = 1.dp,
- modifier = Modifier
- .fillMaxWidth()
- .padding(horizontal = screenWidthDp(4.dp))
- )
+ Spacer(modifier = Modifier.height(screenHeightDp(13.dp)))
+ HorizontalDivider(
+ color = SpotTheme.colors.G300,
+ thickness = 1.dp,
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(horizontal = screenWidthDp(4.dp))
+ )
+ }
}
}
- }
- item {
- Spacer(modifier = Modifier.height(screenHeightDp(13.dp)))
+ item {
+ Spacer(modifier = Modifier.height(screenHeightDp(13.dp)))
- Logout(
- onLogOutClick = {}
- )
+ Logout(
+ onLogOutClick = { logout = true }
+ )
- Spacer(modifier = Modifier.height(screenHeightDp(13.dp)))
+ Spacer(modifier = Modifier.height(screenHeightDp(13.dp)))
- HorizontalDivider(
- color = SpotTheme.colors.G300,
- thickness = 1.dp,
- modifier = Modifier
- .fillMaxWidth()
- .padding(horizontal = screenWidthDp(4.dp))
- )
- }
+ HorizontalDivider(
+ color = SpotTheme.colors.G300,
+ thickness = 1.dp,
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(horizontal = screenWidthDp(4.dp))
+ )
+ }
- item {
- Spacer(modifier = Modifier.height(screenHeightDp(13.dp)))
+ item {
+ Spacer(modifier = Modifier.height(screenHeightDp(13.dp)))
- BlankButton(
- modifier = Modifier
- .width(screenWidthDp(60.dp))
- .height(screenHeightDp(26.dp)),
- state = ImageButtonState.XOUTLINEB100State,
- shape = SpotShapes.Hard,
- onClick = {}
- ) {
- Text(
- text = "회원 탈퇴",
- style = SpotTheme.typography.regular_500,
- color = SpotTheme.colors.G400,
- textDecoration = TextDecoration.Underline,
+ BlankButton(
modifier = Modifier
- .padding(horizontal = screenWidthDp(8.dp), vertical = screenHeightDp(4.dp))
- )
+ .width(screenWidthDp(60.dp))
+ .height(screenHeightDp(26.dp)),
+ state = ImageButtonState.XOUTLINEB100State,
+ shape = SpotShapes.Hard,
+ onClick = onCancelMemberShipClick
+ ) {
+ Text(
+ text = "회원 탈퇴",
+ style = SpotTheme.typography.regular_500,
+ color = SpotTheme.colors.G400,
+ textDecoration = TextDecoration.Underline,
+ modifier = Modifier
+ .padding(horizontal = screenWidthDp(8.dp), vertical = screenHeightDp(4.dp))
+ )
+ }
}
}
+
+ AcceptDialog(
+ visible = logout,
+ painter = painterResource(R.drawable.logout),
+ painterTint = SpotTheme.colors.G400,
+ modalTitle = "로그아웃 할까요?",
+ modalDes = null,
+ okButtonText = "로그아웃",
+ noButtonText = "취소",
+ onClick = {
+ successLogout = true
+ logout = false
+ },
+ onDismiss = {
+ logout = false
+ }
+ )
+
+ AcceptDialog(
+ visible = successLogout,
+ painter = painterResource(R.drawable.ic_check),
+ painterTint = SpotTheme.colors.B500,
+ modalTitle = "로그아웃 처리 완료",
+ modalDes = null,
+ okButtonText = "확인",
+ noButtonText = null,
+ onClick = {
+ successLogout = false
+ onLogoutClick()
+ },
+ onDismiss = {
+ successLogout = false
+ onLogoutClick()
+ }
+ )
}
}
diff --git a/feature/mypage/src/main/java/com/umcspot/spot/mypage/main/navigation/MypageNavigation.kt b/feature/mypage/src/main/java/com/umcspot/spot/mypage/main/navigation/MypageNavigation.kt
index ff3f349a..62064d84 100644
--- a/feature/mypage/src/main/java/com/umcspot/spot/mypage/main/navigation/MypageNavigation.kt
+++ b/feature/mypage/src/main/java/com/umcspot/spot/mypage/main/navigation/MypageNavigation.kt
@@ -20,6 +20,8 @@ fun NavGraphBuilder.mypageGraph(
onMyAppliedClick : () -> Unit,
onEditInterestClick : () -> Unit,
onEditInterestLocationClick : () -> Unit,
+ onCancelMemberShipClick: () -> Unit,
+ onLogoutClick: () -> Unit
) {
composable {
MyPageScreen(
@@ -28,7 +30,9 @@ fun NavGraphBuilder.mypageGraph(
onMyRecruitingClick = onMyRecruitingClick,
onMyAppliedClick = onMyAppliedClick,
onEditInterestClick = onEditInterestClick,
- onEditInterestLocationClick = onEditInterestLocationClick
+ onEditInterestLocationClick = onEditInterestLocationClick,
+ onCancelMemberShipClick = onCancelMemberShipClick,
+ onLogoutClick = onLogoutClick
)
}
}
diff --git a/feature/mypage/src/main/java/com/umcspot/spot/mypage/participating/ParticipatingStudyScreen.kt b/feature/mypage/src/main/java/com/umcspot/spot/mypage/participating/ParticipatingStudyScreen.kt
index bed134e9..e4a07bb8 100644
--- a/feature/mypage/src/main/java/com/umcspot/spot/mypage/participating/ParticipatingStudyScreen.kt
+++ b/feature/mypage/src/main/java/com/umcspot/spot/mypage/participating/ParticipatingStudyScreen.kt
@@ -137,7 +137,8 @@ fun ParticipatingScreen(
onStudyClick = onStudyClick,
onEditClick = {},
onReportClick = {},
- onLeaveClick = {}
+ onLeaveClick = {},
+ onDeleteClick = {}
)
}
}
@@ -151,7 +152,8 @@ fun ParticipatingStudyScreenContent(
onStudyClick: (Long) -> Unit,
onEditClick: (Long) -> Unit,
onReportClick: (Long) -> Unit,
- onLeaveClick: (Long) -> Unit
+ onLeaveClick: (Long) -> Unit,
+ onDeleteClick: (Long) -> Unit
) {
var expandedForId by remember { mutableStateOf(null) }
@@ -193,11 +195,13 @@ fun ParticipatingStudyScreenContent(
MeetballMenu(
isOwner = item.isOwner ,
+ isAlone = item.isAlone,
expanded = expandedForId == item.id,
onDismiss = { expandedForId = null },
onEdit = { expandedForId = null; onEditClick(item.id) },
onReport = { expandedForId = null; onReportClick(item.id) },
onLeave = { expandedForId = null; onLeaveClick(item.id) },
+ onDelete = { expandedForId = null; onDeleteClick(item.id) }
)
}
}
@@ -221,11 +225,13 @@ fun ParticipatingStudyScreenContent(
@Composable
fun MeetballMenu(
isOwner: Boolean,
+ isAlone: Boolean,
expanded: Boolean,
onDismiss: () -> Unit,
onEdit: () -> Unit,
onReport: () -> Unit,
- onLeave: () -> Unit
+ onLeave: () -> Unit,
+ onDelete:() -> Unit
) {
DropdownMenu(
modifier = Modifier
@@ -251,47 +257,56 @@ fun MeetballMenu(
onEdit()
}
)
- HorizontalDivider(
- modifier = Modifier.fillMaxWidth(),
- thickness = 1.dp,
- color = SpotTheme.colors.gray200
- )
}
- DropdownMenuItem(
- modifier = Modifier
- .height(screenHeightDp(30.dp))
- .wrapContentWidth(),
- text = {
- Text(
- text = "스터디원 신고",
- style = SpotTheme.typography.regular_500,
- color = SpotTheme.colors.black
+
+ if(!isAlone) {
+ if(isOwner) {
+ HorizontalDivider(
+ modifier = Modifier.fillMaxWidth(),
+ thickness = 1.dp,
+ color = SpotTheme.colors.gray200
)
- },
- onClick = {
- onDismiss()
- onReport()
}
- )
+
+ DropdownMenuItem(
+ modifier = Modifier
+ .height(screenHeightDp(30.dp))
+ .wrapContentWidth(),
+ text = {
+ Text(
+ text = "스터디원 신고",
+ style = SpotTheme.typography.regular_500,
+ color = SpotTheme.colors.black
+ )
+ },
+ onClick = {
+ onDismiss()
+ onReport()
+ }
+ )
+ }
+
HorizontalDivider(
modifier = Modifier.fillMaxWidth(),
thickness = 1.dp,
color = SpotTheme.colors.gray200
)
+
DropdownMenuItem(
modifier = Modifier
.height(screenHeightDp(30.dp))
.wrapContentWidth(),
text = {
Text(
- text = "스터디 나가기",
+ text = if(isAlone) "스터디 삭제하기" else "스터디 나가기",
style = SpotTheme.typography.regular_500,
color = SpotTheme.colors.R500
)
},
onClick = {
onDismiss()
- onLeave()
+ if(isAlone) onDelete()
+ else onLeave()
}
)
}
diff --git a/feature/signup/src/main/java/com/umcspot/spot/signup/navigation/SignUpNavigation.kt b/feature/signup/src/main/java/com/umcspot/spot/signup/navigation/SignUpNavigation.kt
index 157775c9..8bdb398d 100644
--- a/feature/signup/src/main/java/com/umcspot/spot/signup/navigation/SignUpNavigation.kt
+++ b/feature/signup/src/main/java/com/umcspot/spot/signup/navigation/SignUpNavigation.kt
@@ -24,6 +24,10 @@ fun NavController.navigateToSaving(navOptions: NavOptions? = null) {
navigate(Saving, navOptions)
}
+fun NavController.navigateToLanding(navOptions: NavOptions? = null) {
+ navigate(Landing, navOptions)
+}
+
fun NavGraphBuilder.signupGraph(
navigateToSignUp: () -> Unit,
navigateToCheckList: () -> Unit,