From ceae1957abf1ca49d6b0c3ca29e69382fbb1d7f0 Mon Sep 17 00:00:00 2001 From: jhg3410 Date: Mon, 5 Aug 2024 00:37:14 +0900 Subject: [PATCH 01/15] =?UTF-8?q?moneymong-485=20fix:=20Custom=20Popup=20?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EA=B8=B0=EC=A1=B4=20=EC=9D=B4=EC=8A=88(?= =?UTF-8?q?=ED=9D=B0=EC=83=89=EC=A4=84)=20=EB=8C=80=EC=9D=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../view/onboarding/LedgerOnboarding.kt | 26 +---- .../onboarding/popup/LedgerOnboardingPopup.kt | 39 ++++++++ .../popup/LedgerOnboardingPopupLayout.kt | 95 +++++++++++++++++++ 3 files changed, 136 insertions(+), 24 deletions(-) create mode 100644 feature/ledger/src/main/java/com/moneymong/moneymong/ledger/view/onboarding/popup/LedgerOnboardingPopup.kt create mode 100644 feature/ledger/src/main/java/com/moneymong/moneymong/ledger/view/onboarding/popup/LedgerOnboardingPopupLayout.kt diff --git a/feature/ledger/src/main/java/com/moneymong/moneymong/ledger/view/onboarding/LedgerOnboarding.kt b/feature/ledger/src/main/java/com/moneymong/moneymong/ledger/view/onboarding/LedgerOnboarding.kt index 47a7ae3b..1beb6833 100644 --- a/feature/ledger/src/main/java/com/moneymong/moneymong/ledger/view/onboarding/LedgerOnboarding.kt +++ b/feature/ledger/src/main/java/com/moneymong/moneymong/ledger/view/onboarding/LedgerOnboarding.kt @@ -9,15 +9,11 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.unit.IntOffset -import androidx.compose.ui.unit.IntRect import androidx.compose.ui.unit.IntSize -import androidx.compose.ui.unit.LayoutDirection -import androidx.compose.ui.window.Popup -import androidx.compose.ui.window.PopupPositionProvider import com.google.accompanist.systemuicontroller.rememberSystemUiController import com.moneymong.moneymong.design_system.theme.Gray10 import com.moneymong.moneymong.design_system.theme.White +import com.moneymong.moneymong.ledger.view.onboarding.popup.LedgerOnboardingPopup import java.time.LocalDate @@ -68,9 +64,7 @@ internal fun LedgerOnboarding( } } - Popup( - popupPositionProvider = LedgerPopupPositionProvider() - ) { + LedgerOnboardingPopup { when (currentPage) { LedgerOnboardingPage.DATE -> { LedgerOnboardingDatePage( @@ -101,20 +95,4 @@ internal fun LedgerOnboarding( } } } -} - - -private class LedgerPopupPositionProvider : PopupPositionProvider { - override fun calculatePosition( - anchorBounds: IntRect, - windowSize: IntSize, - layoutDirection: LayoutDirection, - popupContentSize: IntSize - ): IntOffset { - - return IntOffset( - x = 0, - y = 0 - ) - } } \ No newline at end of file diff --git a/feature/ledger/src/main/java/com/moneymong/moneymong/ledger/view/onboarding/popup/LedgerOnboardingPopup.kt b/feature/ledger/src/main/java/com/moneymong/moneymong/ledger/view/onboarding/popup/LedgerOnboardingPopup.kt new file mode 100644 index 00000000..5e6649ec --- /dev/null +++ b/feature/ledger/src/main/java/com/moneymong/moneymong/ledger/view/onboarding/popup/LedgerOnboardingPopup.kt @@ -0,0 +1,39 @@ +package com.moneymong.moneymong.ledger.view.onboarding.popup + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCompositionContext +import androidx.compose.runtime.rememberUpdatedState +import androidx.compose.ui.platform.LocalView + +@Composable +internal fun LedgerOnboardingPopup( + content: @Composable () -> Unit +) { + val view = LocalView.current + val parentComposition = rememberCompositionContext() + val currentContent by rememberUpdatedState(content) + val popupLayout = remember { + LedgerOnboardingPopupLayout( + composeView = view + ).apply { + setContent(parentComposition) { + currentContent() + } + } + } + + DisposableEffect(key1 = popupLayout) { + popupLayout.show() + + onDispose { + popupLayout.disposeComposition() + popupLayout.dismiss() + } + } +} + + + diff --git a/feature/ledger/src/main/java/com/moneymong/moneymong/ledger/view/onboarding/popup/LedgerOnboardingPopupLayout.kt b/feature/ledger/src/main/java/com/moneymong/moneymong/ledger/view/onboarding/popup/LedgerOnboardingPopupLayout.kt new file mode 100644 index 00000000..d490c94c --- /dev/null +++ b/feature/ledger/src/main/java/com/moneymong/moneymong/ledger/view/onboarding/popup/LedgerOnboardingPopupLayout.kt @@ -0,0 +1,95 @@ +package com.moneymong.moneymong.ledger.view.onboarding.popup + +import android.annotation.SuppressLint +import android.content.Context +import android.graphics.PixelFormat +import android.view.Gravity +import android.view.View +import android.view.WindowManager +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionContext +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import androidx.compose.ui.platform.AbstractComposeView +import androidx.lifecycle.findViewTreeLifecycleOwner +import androidx.lifecycle.findViewTreeViewModelStoreOwner +import androidx.lifecycle.setViewTreeLifecycleOwner +import androidx.lifecycle.setViewTreeViewModelStoreOwner +import androidx.savedstate.findViewTreeSavedStateRegistryOwner +import androidx.savedstate.setViewTreeSavedStateRegistryOwner + + +@SuppressLint("ViewConstructor") +internal class LedgerOnboardingPopupLayout( + private val composeView: View, +) : AbstractComposeView(composeView.context) { + + private val windowManager = + composeView.context.getSystemService(Context.WINDOW_SERVICE) as WindowManager + private val params = createLayoutParams() + private var content: @Composable () -> Unit by mutableStateOf({}) + + + init { + id = android.R.id.content + setViewTreeLifecycleOwner(composeView.findViewTreeLifecycleOwner()) + setViewTreeViewModelStoreOwner(composeView.findViewTreeViewModelStoreOwner()) + setViewTreeSavedStateRegistryOwner(composeView.findViewTreeSavedStateRegistryOwner()) + } + + @Composable + override fun Content() { + content() + } + + fun setContent(parent: CompositionContext, content: @Composable () -> Unit) { + setParentCompositionContext(parent) + this.content = content + } + + fun show() { + windowManager.addView(this, params) + } + + fun dismiss() { + setViewTreeLifecycleOwner(null) + windowManager.removeViewImmediate(this) + } + + + private fun createLayoutParams(): WindowManager.LayoutParams { + return WindowManager.LayoutParams().apply { + // Start to position the popup in the top left corner, a new position will be calculated + gravity = Gravity.START or Gravity.TOP + + // Flags specific to android.widget.PopupWindow + flags = flags and ( + WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES or + WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE or + WindowManager.LayoutParams.FLAG_SPLIT_TOUCH + ).inv() + + // Make the popup window not focusable + flags = flags or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE + + // Enables us to intercept outside clicks even when popup is not focusable + flags = flags or WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH + + type = WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL + + // Get the Window token from the parent view + token = composeView.applicationWindowToken + + // Set the popup window to occupy the entire screen + width = WindowManager.LayoutParams.MATCH_PARENT + height = WindowManager.LayoutParams.MATCH_PARENT + + format = PixelFormat.TRANSLUCENT + + // accessibilityTitle is not exposed as a public API therefore we set popup window + // title which is used as a fallback by a11y services + title = "LedgerOnboardingPopup" + } + } +} \ No newline at end of file From 9308c97776b4e2709a4aa9daa9b63d25174c9a68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B8=B0=EC=9D=80=EC=84=9C?= <101038047+eunseo0105@users.noreply.github.com> Date: Wed, 7 Aug 2024 22:12:50 +0900 Subject: [PATCH 02/15] =?UTF-8?q?Feat.=EC=86=8C=EC=86=8D=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/res/drawable/ic_agency_delete.png | Bin 0 -> 1216 bytes .../moneymong/network/api/AgencyApi.kt | 7 +++ .../member/MemberRemoteDataSource.kt | 2 + .../member/MemberRemoteDataSourceImpl.kt | 4 ++ .../repository/member/MemberRepositoryImpl.kt | 4 ++ .../repository/member/MemberRepository.kt | 2 + .../usecase/member/AgencyDeleteUseCase.kt | 12 +++++ .../moneymong/ledger/LedgerScreen.kt | 12 ++++- .../moneymong/ledger/LedgerViewModel.kt | 49 +++++++++++++---- .../java/com/example/member/MemberScreen.kt | 49 ++++++++++++++++- .../java/com/example/member/MemberState.kt | 2 + .../com/example/member/MemberViewModel.kt | 50 +++++++++++++++++- .../member/component/MemberCardView.kt | 25 +++++++++ 13 files changed, 205 insertions(+), 13 deletions(-) create mode 100644 core/design-system/src/main/res/drawable/ic_agency_delete.png create mode 100644 domain/src/main/java/com/moneymong/moneymong/domain/usecase/member/AgencyDeleteUseCase.kt diff --git a/core/design-system/src/main/res/drawable/ic_agency_delete.png b/core/design-system/src/main/res/drawable/ic_agency_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..7a3b6b7f7f7fbffae7e13781f57625e3d6b41ec4 GIT binary patch literal 1216 zcmV;x1V8(UP)@~0drDELIAGL9O(c600d`2O+f$vv5yPt3W#N_@(tJl2v+$9yji9EtpIqVO3>^;T!C=~#uXS}C7Jg2 zfC`oFA^kV$g88Z_Qr(@I$(f$p_w;lFH8nLgH8nMN6heiF&T1RYB!fU3HVEotJnmC( ze}IapL?F>!&49)xf6U;AK5}tDA9s%snBW45?yEgM%_@Q*_UUwY4FL%%ka)3v$dA)9 zLLzWPXFDqhM1nww?#5UUD!VHNK-dh8T_KICu}?nG_)yC7qJm zAw+%*BC{VOL<>o>s2KrUNE6wMw&0mC0)ZAa6@9+b3$}Nf(}XRgjnDjXUUAN+2tcS9 zG_NeBWX0t%xcn}y8J*LSPy)47h4kTFACA!J`*Rqa)0JSO*j=F(=oU(cc@BzlbXbOQ z_oYqE5x3z5Z^!5KAn%oVJFP(C#p`(f-x6JE55pE+eIH7gKE2hlV^T6Om` zkL~}Wj)xZ)0~lf~5S?gaKun{Uddk;gKHRnkDNj@^PM9%8P*-E+D{Te(g;;57l0+dY z6-b@3rx9e+B31Vwi!54VDNwHNL83AHIOI8_w-hL1!|Ktf7KeikF&kEoMpa@b&^0uW@_NMpfb>khx)d#VZ#} zqgosiw!~;yJsVYty+HTGusR5&F@Kai#>~*Hwzo8@5|<#Y3znI9zP^Ntx!UoQDJzqF z085;9`-txPPw28|LXRJ}Z>WT#=VZz%fdQTE%)t`J%`9}lSD;?AEYRWl4ra~G6=lY_ znbpx~Uq5*k0dmRRD4#l|P~jxdr2$NyA-yD{~oVzFkz;uJ}y z6JF+nifp&hT;K~kn6XfDKiM|M<0n40UP;32S?z9QoCeIJy7?jbsP{Q0_CxGjt*NQ0 esi~>Cll%el-HxngB5MQy0000 + + //DELETE + @DELETE("api/v1/agencies/{agencyId}") + suspend fun deleteAgency( + @Path("agencyId") agencyId: Int + ) : Result } \ No newline at end of file diff --git a/data/src/main/java/com/moneymong/moneymong/data/datasource/member/MemberRemoteDataSource.kt b/data/src/main/java/com/moneymong/moneymong/data/datasource/member/MemberRemoteDataSource.kt index 8b5713b9..da900da5 100644 --- a/data/src/main/java/com/moneymong/moneymong/data/datasource/member/MemberRemoteDataSource.kt +++ b/data/src/main/java/com/moneymong/moneymong/data/datasource/member/MemberRemoteDataSource.kt @@ -11,4 +11,6 @@ interface MemberRemoteDataSource { suspend fun getMemberLists(agencyId: Long): Result suspend fun updateMemberAuthor(agencyId : Long, data : UpdateAuthorRequest) : Result suspend fun blockMemberAuthor(agencyId: Long, data : MemberBlockRequest) : Result + suspend fun deleteAgency(agencyId: Int) : Result + } \ No newline at end of file diff --git a/data/src/main/java/com/moneymong/moneymong/data/datasource/member/MemberRemoteDataSourceImpl.kt b/data/src/main/java/com/moneymong/moneymong/data/datasource/member/MemberRemoteDataSourceImpl.kt index 222d5038..0cdcc50c 100644 --- a/data/src/main/java/com/moneymong/moneymong/data/datasource/member/MemberRemoteDataSourceImpl.kt +++ b/data/src/main/java/com/moneymong/moneymong/data/datasource/member/MemberRemoteDataSourceImpl.kt @@ -31,4 +31,8 @@ class MemberRemoteDataSourceImpl @Inject constructor( override suspend fun blockMemberAuthor(agencyId: Long, data: MemberBlockRequest): Result { return memberApi.blockMemberAuthor(agencyId, data) } + + override suspend fun deleteAgency(agencyId: Int): Result { + return agencyApi.deleteAgency(agencyId) + } } \ No newline at end of file diff --git a/data/src/main/java/com/moneymong/moneymong/data/repository/member/MemberRepositoryImpl.kt b/data/src/main/java/com/moneymong/moneymong/data/repository/member/MemberRepositoryImpl.kt index 50ca2298..8bfc4841 100644 --- a/data/src/main/java/com/moneymong/moneymong/data/repository/member/MemberRepositoryImpl.kt +++ b/data/src/main/java/com/moneymong/moneymong/data/repository/member/MemberRepositoryImpl.kt @@ -31,4 +31,8 @@ class MemberRepositoryImpl @Inject constructor( return memberRemoteDataSource.blockMemberAuthor(agencyId, data) } + + override suspend fun deleteAgency(agencyId: Int): Result { + return memberRemoteDataSource.deleteAgency(agencyId) + } } \ No newline at end of file diff --git a/domain/src/main/java/com/moneymong/moneymong/domain/repository/member/MemberRepository.kt b/domain/src/main/java/com/moneymong/moneymong/domain/repository/member/MemberRepository.kt index c789f21c..4ff59b80 100644 --- a/domain/src/main/java/com/moneymong/moneymong/domain/repository/member/MemberRepository.kt +++ b/domain/src/main/java/com/moneymong/moneymong/domain/repository/member/MemberRepository.kt @@ -11,4 +11,6 @@ interface MemberRepository { suspend fun getMemberLists(agencyId: Long) : Result suspend fun updateMemberAuthor(agencyId : Long, data : UpdateAuthorRequest) : Result suspend fun blockMemberAuthor(agencyId: Long, data: MemberBlockRequest) : Result + suspend fun deleteAgency(agencyId: Int) :Result + } \ No newline at end of file diff --git a/domain/src/main/java/com/moneymong/moneymong/domain/usecase/member/AgencyDeleteUseCase.kt b/domain/src/main/java/com/moneymong/moneymong/domain/usecase/member/AgencyDeleteUseCase.kt new file mode 100644 index 00000000..a6b57b25 --- /dev/null +++ b/domain/src/main/java/com/moneymong/moneymong/domain/usecase/member/AgencyDeleteUseCase.kt @@ -0,0 +1,12 @@ +package com.moneymong.moneymong.domain.usecase.member + +import com.moneymong.moneymong.domain.repository.member.MemberRepository +import javax.inject.Inject + +class AgencyDeleteUseCase @Inject constructor( + private val memberRepository: MemberRepository +) { + suspend operator fun invoke(agencyId: Int) : Result { + return memberRepository.deleteAgency(agencyId) + } +} \ No newline at end of file diff --git a/feature/ledger/src/main/java/com/moneymong/moneymong/ledger/LedgerScreen.kt b/feature/ledger/src/main/java/com/moneymong/moneymong/ledger/LedgerScreen.kt index 36d6afaa..d8c5685b 100644 --- a/feature/ledger/src/main/java/com/moneymong/moneymong/ledger/LedgerScreen.kt +++ b/feature/ledger/src/main/java/com/moneymong/moneymong/ledger/LedgerScreen.kt @@ -333,7 +333,17 @@ fun LedgerScreen( } } else { Box(modifier = modifier.fillMaxSize()) { - MemberScreen(agencyId = state.agencyId) + MemberScreen( + agencyId = state.agencyId, + agencyList = state.agencyList, + onClickItem = { + viewModel.eventEmit( + LedgerSideEffect.LedgerSelectedAgencyChange( + it + ) + ) + }, + changeAgencyList = { viewModel.changeAgencyList(it) }) } } } diff --git a/feature/ledger/src/main/java/com/moneymong/moneymong/ledger/LedgerViewModel.kt b/feature/ledger/src/main/java/com/moneymong/moneymong/ledger/LedgerViewModel.kt index e3aa1497..1f3116ad 100644 --- a/feature/ledger/src/main/java/com/moneymong/moneymong/ledger/LedgerViewModel.kt +++ b/feature/ledger/src/main/java/com/moneymong/moneymong/ledger/LedgerViewModel.kt @@ -1,5 +1,6 @@ package com.moneymong.moneymong.ledger +import android.util.Log import androidx.lifecycle.SavedStateHandle import com.moneymong.moneymong.common.base.BaseViewModel import com.moneymong.moneymong.common.error.MoneyMongError @@ -14,6 +15,7 @@ import com.moneymong.moneymong.domain.usecase.member.MemberListUseCase import com.moneymong.moneymong.domain.usecase.user.FetchUserIdUseCase import com.moneymong.moneymong.ledger.navigation.LedgerArgs import com.moneymong.moneymong.ledger.view.LedgerTransactionType +import com.moneymong.moneymong.model.agency.MyAgencyResponse import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.collectLatest import org.orbitmvi.orbit.annotation.OrbitExperimental @@ -69,6 +71,7 @@ class LedgerViewModel @Inject constructor( reduce { state.copy(isAgencyExistLoading = true) } fetchAgencyExistLedgerUseCase(state.agencyId) .onSuccess { + Log.d("fetchAgencyExistLedger${state.agencyId}",it.toString() ) reduce { state.copy( isExistLedger = it, @@ -90,6 +93,8 @@ class LedgerViewModel @Inject constructor( page = 0, limit = 100 ).onSuccess { + Log.d("fetchLedgerTransactionList${state.existAgency}",it.toString() ) + reduce { state.copy( ledgerTransaction = it, @@ -97,11 +102,17 @@ class LedgerViewModel @Inject constructor( ) } }.onFailure { - reduce { + if (it.message.equals("장부가 존재하지 않습니다.")) { //TODO - 서버 의논 후 변경 예정 state.copy( - visibleError = true, - errorMessage = it.message ?: MoneyMongError.UnExpectedError.message + visibleError = false, ) + } else { + reduce { + state.copy( + visibleError = true, + errorMessage = it.message ?: MoneyMongError.UnExpectedError.message + ) + } } }.also { reduce { state.copy(isLedgerTransactionLoading = false) } } } @@ -111,6 +122,8 @@ class LedgerViewModel @Inject constructor( reduce { state.copy(isMyAgencyLoading = true) } fetchMyAgencyListUseCase() .onSuccess { + Log.d("fetchMyAgencyList${state.existAgency}",it.toString() ) + reduce { state.copy( agencyList = it, @@ -142,11 +155,20 @@ class LedgerViewModel @Inject constructor( ) } }.onFailure { - reduce { - state.copy( - visibleError = true, - errorMessage = it.message ?: MoneyMongError.UnExpectedError.message - ) + if (it.message.equals("소속에 가입 후 장부를 사용할 수 있습니다.")) { //TODO - 서버 의논 후 변경 예정 + reduce { + state.copy( + visibleError = false + ) + } + } else { + reduce { + state.copy( + visibleError = true, + errorMessage = it.message + ?: MoneyMongError.UnExpectedError.message + ) + } } }.also { reduce { state.copy(isAgencyMemberLoading = false) } } } @@ -216,4 +238,13 @@ class LedgerViewModel @Inject constructor( postDisplayedLedgerOnboardingUseCase(onboardingType = state.onboardingType) reduce { state.copy(visibleOnboarding = false) } } -} \ No newline at end of file + + + fun changeAgencyList(filteredAgencyList: List) = intent { + reduce { + state.copy( + agencyList = filteredAgencyList + ) + } + } +} diff --git a/feature/member/src/main/java/com/example/member/MemberScreen.kt b/feature/member/src/main/java/com/example/member/MemberScreen.kt index e7a4019c..75ee832e 100644 --- a/feature/member/src/main/java/com/example/member/MemberScreen.kt +++ b/feature/member/src/main/java/com/example/member/MemberScreen.kt @@ -37,6 +37,7 @@ import com.moneymong.moneymong.design_system.component.bottomSheet.MDSBottomShee import com.moneymong.moneymong.design_system.component.button.MDSButton import com.moneymong.moneymong.design_system.component.button.MDSButtonSize import com.moneymong.moneymong.design_system.component.button.MDSButtonType +import com.moneymong.moneymong.design_system.component.modal.MDSModal import com.moneymong.moneymong.design_system.component.snackbar.MDSSnackbarHost import com.moneymong.moneymong.design_system.error.ErrorDialog import com.moneymong.moneymong.design_system.error.ErrorScreen @@ -50,6 +51,7 @@ import com.moneymong.moneymong.design_system.theme.Gray08 import com.moneymong.moneymong.design_system.theme.MMHorizontalSpacing import com.moneymong.moneymong.design_system.theme.Red03 import com.moneymong.moneymong.design_system.theme.White +import com.moneymong.moneymong.model.agency.MyAgencyResponse import kotlinx.coroutines.launch import org.orbitmvi.orbit.compose.collectAsState import org.orbitmvi.orbit.compose.collectSideEffect @@ -59,7 +61,10 @@ import org.orbitmvi.orbit.compose.collectSideEffect @Composable fun MemberScreen( viewModel: MemberViewModel = hiltViewModel(), - agencyId: Int + agencyId: Int, + agencyList: List, + onClickItem: (agencyId: Int) -> Unit, + changeAgencyList: (changeAgencyList: List) -> Unit ) { val sheetState = rememberModalBottomSheetState( skipPartiallyExpanded = true, @@ -196,6 +201,44 @@ fun MemberScreen( ) } + if (state.deleteAgency) { + MDSModal( + icon = R.drawable.ic_warning_filled, + title = "소속을 정말 삭제하시겠어요?", + description = "등록된 회비 내역이 모두 사라져요.", + negativeBtnText = "취소", + positiveBtnText = "확인", + onClickNegative = { viewModel.deleteAgencyBtnClicked(false) }, + onClickPositive = { + viewModel.deleteAgency( + agencyId, + agencyList, + onClickItem, + changeAgencyList + ) + } + ) + } + + if (state.deleteAgency) { + MDSModal( + icon = R.drawable.ic_warning_filled, + title = "소속을 정말 삭제하시겠어요?", + description = "등록된 회비 내역이 모두 사라져요.", + negativeBtnText = "취소", + positiveBtnText = "확인", + onClickNegative = { viewModel.deleteAgencyBtnClicked(false) }, + onClickPositive = { + viewModel.deleteAgency( + agencyId, + agencyList, + onClickItem, + changeAgencyList + ) + } + ) + } + if (state.visibleBottomSheet) { viewModel.isRoleChanged(false) MDSBottomSheet( @@ -383,6 +426,8 @@ fun MemberScreen( invitationCode = state.invitationCode, isReInvitationCode = { viewModel.eventEmit(MemberSideEffect.GetReInvitationCode(it)) }, //TODO onCopyChange = { onCopyClick -> viewModel.onCopyClickChanged(onCopyClick) }, + deleteAgencyBtnClicked = { onClick -> viewModel.deleteAgencyBtnClicked(onClick)} + ) MemberListView( @@ -428,6 +473,8 @@ fun MemberScreen( invitationCode = state.invitationCode, isReInvitationCode = { viewModel.eventEmit(MemberSideEffect.GetReInvitationCode(it)) }, onCopyChange = { onCopyClick -> viewModel.onCopyClickChanged(onCopyClick) }, + deleteAgencyBtnClicked = { onClick -> viewModel.deleteAgencyBtnClicked(onClick)} + ) MemberListView( diff --git a/feature/member/src/main/java/com/example/member/MemberState.kt b/feature/member/src/main/java/com/example/member/MemberState.kt index cc11fb63..3a4ae76a 100644 --- a/feature/member/src/main/java/com/example/member/MemberState.kt +++ b/feature/member/src/main/java/com/example/member/MemberState.kt @@ -31,4 +31,6 @@ data class MemberState( val isUserAuthor: String = "", val agencyId: Int = 0, val isBlockedUser : Boolean = false, + val deleteAgency : Boolean = false, + ) : State \ No newline at end of file diff --git a/feature/member/src/main/java/com/example/member/MemberViewModel.kt b/feature/member/src/main/java/com/example/member/MemberViewModel.kt index e0283de1..fe15ac2b 100644 --- a/feature/member/src/main/java/com/example/member/MemberViewModel.kt +++ b/feature/member/src/main/java/com/example/member/MemberViewModel.kt @@ -3,12 +3,14 @@ package com.example.member import android.util.Log import com.moneymong.moneymong.common.base.BaseViewModel import com.moneymong.moneymong.domain.usecase.agency.FetchAgencyIdUseCase +import com.moneymong.moneymong.domain.usecase.member.AgencyDeleteUseCase import com.moneymong.moneymong.domain.usecase.member.MemberBlockUseCase import com.moneymong.moneymong.domain.usecase.member.MemberInvitationCodeUseCase import com.moneymong.moneymong.domain.usecase.member.MemberListUseCase import com.moneymong.moneymong.domain.usecase.member.MemberReInvitationCodeUseCase import com.moneymong.moneymong.domain.usecase.member.UpdateMemberAuthorUseCase import com.moneymong.moneymong.domain.usecase.user.GetMyInfoUseCase +import com.moneymong.moneymong.model.agency.MyAgencyResponse import com.moneymong.moneymong.model.member.AgencyUser import com.moneymong.moneymong.model.member.MemberBlockRequest import com.moneymong.moneymong.model.member.UpdateAuthorRequest @@ -27,7 +29,8 @@ class MemberViewModel @Inject constructor( private val getMyInfoUseCase: GetMyInfoUseCase, private val updateMemberAuthorUseCase: UpdateMemberAuthorUseCase, private val memberBlockUseCase: MemberBlockUseCase, - private val fetchAgencyIdUseCase: FetchAgencyIdUseCase + private val fetchAgencyIdUseCase: FetchAgencyIdUseCase, + private val delecteAgencyUseCase: AgencyDeleteUseCase ) : BaseViewModel(MemberState()) { init { @@ -256,6 +259,7 @@ class MemberViewModel @Inject constructor( } } + fun blockMemberAuthor(agencyId: Long, userId: Long) = intent { memberBlockUseCase(agencyId, MemberBlockRequest(userId)) .onSuccess { @@ -263,7 +267,7 @@ class MemberViewModel @Inject constructor( updateMemberListByBlock(userId) } .onFailure { - reduce{ + reduce { state.copy( visiblePopUpError = true, errorPopUpMessage = it.message.toString() @@ -272,6 +276,48 @@ class MemberViewModel @Inject constructor( } } + + fun deleteAgency( + agencyId: Int, + agencyList: List, + onClickItem: (agencyId: Int) -> Unit, + changeAgencyList: (agencyList: List) -> Unit + ) = intent { + delecteAgencyUseCase.invoke(agencyId) + .onSuccess { + Log.d("deleteAgency${agencyId}", it.toString()) + val filteredList = agencyList.filter { it.id != agencyId } + if (filteredList.isNotEmpty()) { + val randomAgency = filteredList.random() + onClickItem(randomAgency.id) + changeAgencyList(filteredList) + } else { + changeAgencyList(emptyList()) + } + reduce { + state.copy( + deleteAgency = false + ) + } + }.onFailure { + reduce { + state.copy( + visiblePopUpError = true, + errorPopUpMessage = it.message.toString() + ) + } + } + } + + + fun deleteAgencyBtnClicked(deleteAgencyBtnClicked : Boolean) = intent { + reduce { + state.copy( + deleteAgency = deleteAgencyBtnClicked + ) + } + } + private fun updateFilteredMemberListByBlock(userId: Long) = intent { val currentMemberList = state.filteredMemberList val updateBlockedMemberList = currentMemberList.filterNot { member -> diff --git a/feature/member/src/main/java/com/example/member/component/MemberCardView.kt b/feature/member/src/main/java/com/example/member/component/MemberCardView.kt index 42b2336c..b0ca5ba8 100644 --- a/feature/member/src/main/java/com/example/member/component/MemberCardView.kt +++ b/feature/member/src/main/java/com/example/member/component/MemberCardView.kt @@ -5,6 +5,7 @@ import android.content.ClipboardManager import android.content.Context import androidx.compose.foundation.Image import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth @@ -31,6 +32,7 @@ import com.moneymong.moneymong.design_system.theme.Body4 import com.moneymong.moneymong.design_system.theme.Gray02 import com.moneymong.moneymong.design_system.theme.Gray10 import com.moneymong.moneymong.design_system.theme.Mint03 +import com.moneymong.moneymong.design_system.theme.Red03 import com.moneymong.moneymong.design_system.theme.White import com.moneymong.moneymong.model.member.AgencyUser @@ -45,6 +47,8 @@ fun MemberCardView( invitationCode: String, isReInvitationCode: (Long) -> Unit, onCopyChange: (Boolean) -> Unit, + deleteAgencyBtnClicked : (Boolean) -> Unit + ) { val context = LocalContext.current @@ -92,6 +96,27 @@ fun MemberCardView( contentColor = White, ) + if(memberMyInfo.agencyUserRole != "MEMBER"){ + Row ( + modifier = Modifier + .fillMaxWidth() + .noRippleClickable { deleteAgencyBtnClicked(true) }, + horizontalArrangement = Arrangement.End, + verticalAlignment = Alignment.CenterVertically + ){ + Text( + text = "소속삭제", + color = Red03, + style = Body3 + ) + Image( + modifier= Modifier.size(18.dp), + painter =painterResource(id = R.drawable.ic_agency_delete), + contentDescription ="" + ) + + } + } } if (memberMyInfo.agencyUserRole == "STAFF") { From d787edc4b1037d1dde221820b45baa65862b2a50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B8=B0=EC=9D=80=EC=84=9C?= <101038047+eunseo0105@users.noreply.github.com> Date: Wed, 7 Aug 2024 22:13:20 +0900 Subject: [PATCH 03/15] =?UTF-8?q?Fix:=20Agency.kt=20=EC=9E=84=EC=8B=9C=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../moneymong/moneymong/feature/agency/search/Agency.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/Agency.kt b/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/Agency.kt index 594479fe..0f5d6ea2 100644 --- a/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/Agency.kt +++ b/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/Agency.kt @@ -16,6 +16,7 @@ fun AgencyGetResponse.toAgency(): Agency { type = when (this.type) { "IN_SCHOOL_CLUB" -> AgencyType.CLUB "STUDENT_COUNCIL" -> AgencyType.COUNCIL + "GENERAL" -> AgencyType.GENERAL //임의로 설정 -> 추후 소속 코드 반영 else -> throw IllegalArgumentException("Unknown type: $type") }, name = this.name, @@ -29,6 +30,7 @@ fun MyAgencyResponse.toAgency(): Agency { type = when (this.type) { "IN_SCHOOL_CLUB" -> AgencyType.CLUB "STUDENT_COUNCIL" -> AgencyType.COUNCIL + "GENERAL" -> AgencyType.GENERAL //임의로 설정 -> 추후 소속 코드 반영 else -> throw IllegalArgumentException("Unknown type: $type") }, name = this.name, @@ -38,10 +40,13 @@ fun MyAgencyResponse.toAgency(): Agency { enum class AgencyType(val text: String) { CLUB(text = "동아리"), - COUNCIL(text = "학생회"); + COUNCIL(text = "학생회"), + GENERAL(text ="기타"); //임의로 설정 -> 추후 소속 코드 반영 fun agencyRegisterTypeToString(): String = when (this) { CLUB -> "IN_SCHOOL_CLUB" COUNCIL -> "STUDENT_COUNCIL" + GENERAL -> "IN_SCHOOL_CLUB" //임의로 설정 -> 추후 소속 코드 반영 + } } \ No newline at end of file From a4dc6a8b9bca9f21c59fe26632f2b353df2dc92d Mon Sep 17 00:00:00 2001 From: eunseo Date: Sat, 10 Aug 2024 22:03:54 +0900 Subject: [PATCH 04/15] =?UTF-8?q?Fix:=20=ED=9D=AC=EC=A7=81=EB=8B=98=20?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../usecase/member/AgencyDeleteUseCase.kt | 2 +- .../moneymong/ledger/LedgerViewModel.kt | 10 ++++---- .../java/com/example/member/MemberScreen.kt | 23 ++----------------- .../com/example/member/MemberViewModel.kt | 7 +++--- 4 files changed, 13 insertions(+), 29 deletions(-) diff --git a/domain/src/main/java/com/moneymong/moneymong/domain/usecase/member/AgencyDeleteUseCase.kt b/domain/src/main/java/com/moneymong/moneymong/domain/usecase/member/AgencyDeleteUseCase.kt index a6b57b25..c9a6fc3e 100644 --- a/domain/src/main/java/com/moneymong/moneymong/domain/usecase/member/AgencyDeleteUseCase.kt +++ b/domain/src/main/java/com/moneymong/moneymong/domain/usecase/member/AgencyDeleteUseCase.kt @@ -3,7 +3,7 @@ package com.moneymong.moneymong.domain.usecase.member import com.moneymong.moneymong.domain.repository.member.MemberRepository import javax.inject.Inject -class AgencyDeleteUseCase @Inject constructor( +class DeleteAgencyUseCase @Inject constructor( private val memberRepository: MemberRepository ) { suspend operator fun invoke(agencyId: Int) : Result { diff --git a/feature/ledger/src/main/java/com/moneymong/moneymong/ledger/LedgerViewModel.kt b/feature/ledger/src/main/java/com/moneymong/moneymong/ledger/LedgerViewModel.kt index 1f3116ad..33765868 100644 --- a/feature/ledger/src/main/java/com/moneymong/moneymong/ledger/LedgerViewModel.kt +++ b/feature/ledger/src/main/java/com/moneymong/moneymong/ledger/LedgerViewModel.kt @@ -102,10 +102,12 @@ class LedgerViewModel @Inject constructor( ) } }.onFailure { - if (it.message.equals("장부가 존재하지 않습니다.")) { //TODO - 서버 의논 후 변경 예정 - state.copy( - visibleError = false, - ) + if (it.message.equals("장부가 존재하지 않습니다.")) { + reduce { //TODO - 서버 의논 후 변경 예정 + state.copy( + visibleError = false, + ) + } } else { reduce { state.copy( diff --git a/feature/member/src/main/java/com/example/member/MemberScreen.kt b/feature/member/src/main/java/com/example/member/MemberScreen.kt index 75ee832e..be6ce479 100644 --- a/feature/member/src/main/java/com/example/member/MemberScreen.kt +++ b/feature/member/src/main/java/com/example/member/MemberScreen.kt @@ -63,7 +63,7 @@ fun MemberScreen( viewModel: MemberViewModel = hiltViewModel(), agencyId: Int, agencyList: List, - onClickItem: (agencyId: Int) -> Unit, + changeAgency: (agencyId: Int) -> Unit, changeAgencyList: (changeAgencyList: List) -> Unit ) { val sheetState = rememberModalBottomSheetState( @@ -213,26 +213,7 @@ fun MemberScreen( viewModel.deleteAgency( agencyId, agencyList, - onClickItem, - changeAgencyList - ) - } - ) - } - - if (state.deleteAgency) { - MDSModal( - icon = R.drawable.ic_warning_filled, - title = "소속을 정말 삭제하시겠어요?", - description = "등록된 회비 내역이 모두 사라져요.", - negativeBtnText = "취소", - positiveBtnText = "확인", - onClickNegative = { viewModel.deleteAgencyBtnClicked(false) }, - onClickPositive = { - viewModel.deleteAgency( - agencyId, - agencyList, - onClickItem, + changeAgency, changeAgencyList ) } diff --git a/feature/member/src/main/java/com/example/member/MemberViewModel.kt b/feature/member/src/main/java/com/example/member/MemberViewModel.kt index fe15ac2b..460f31b7 100644 --- a/feature/member/src/main/java/com/example/member/MemberViewModel.kt +++ b/feature/member/src/main/java/com/example/member/MemberViewModel.kt @@ -3,7 +3,7 @@ package com.example.member import android.util.Log import com.moneymong.moneymong.common.base.BaseViewModel import com.moneymong.moneymong.domain.usecase.agency.FetchAgencyIdUseCase -import com.moneymong.moneymong.domain.usecase.member.AgencyDeleteUseCase +import com.moneymong.moneymong.domain.usecase.member.DeleteAgencyUseCase import com.moneymong.moneymong.domain.usecase.member.MemberBlockUseCase import com.moneymong.moneymong.domain.usecase.member.MemberInvitationCodeUseCase import com.moneymong.moneymong.domain.usecase.member.MemberListUseCase @@ -30,7 +30,7 @@ class MemberViewModel @Inject constructor( private val updateMemberAuthorUseCase: UpdateMemberAuthorUseCase, private val memberBlockUseCase: MemberBlockUseCase, private val fetchAgencyIdUseCase: FetchAgencyIdUseCase, - private val delecteAgencyUseCase: AgencyDeleteUseCase + private val deleteAgencyUseCase: DeleteAgencyUseCase ) : BaseViewModel(MemberState()) { init { @@ -283,7 +283,7 @@ class MemberViewModel @Inject constructor( onClickItem: (agencyId: Int) -> Unit, changeAgencyList: (agencyList: List) -> Unit ) = intent { - delecteAgencyUseCase.invoke(agencyId) + deleteAgencyUseCase.invoke(agencyId) .onSuccess { Log.d("deleteAgency${agencyId}", it.toString()) val filteredList = agencyList.filter { it.id != agencyId } @@ -302,6 +302,7 @@ class MemberViewModel @Inject constructor( }.onFailure { reduce { state.copy( + deleteAgency = false, visiblePopUpError = true, errorPopUpMessage = it.message.toString() ) From 8aa8fa2e6eb254fb4e949218e05d233a65f49d8b Mon Sep 17 00:00:00 2001 From: jhg3410 Date: Thu, 25 Jul 2024 16:01:12 +0900 Subject: [PATCH 05/15] =?UTF-8?q?MONEYMONG-494=20feat:=20selection=20disab?= =?UTF-8?q?led=20=ED=83=80=EC=9E=85=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../component/selection/Selection.kt | 74 +++++++++++-------- .../component/selection/SelectionDefaults.kt | 66 +++++++++++++++++ .../component/selection/SelectionType.kt | 25 ------- 3 files changed, 108 insertions(+), 57 deletions(-) create mode 100644 core/design-system/src/main/java/com/moneymong/moneymong/design_system/component/selection/SelectionDefaults.kt delete mode 100644 core/design-system/src/main/java/com/moneymong/moneymong/design_system/component/selection/SelectionType.kt diff --git a/core/design-system/src/main/java/com/moneymong/moneymong/design_system/component/selection/Selection.kt b/core/design-system/src/main/java/com/moneymong/moneymong/design_system/component/selection/Selection.kt index 782fbab9..60cae240 100644 --- a/core/design-system/src/main/java/com/moneymong/moneymong/design_system/component/selection/Selection.kt +++ b/core/design-system/src/main/java/com/moneymong/moneymong/design_system/component/selection/Selection.kt @@ -6,40 +6,43 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box 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.shape.RoundedCornerShape import androidx.compose.material.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.moneymong.moneymong.design_system.theme.Body3 -import com.moneymong.moneymong.design_system.theme.Gray03 @Composable fun MDSSelection( modifier: Modifier = Modifier, text: String, - isSelected: Boolean, + enabled: Boolean = true, + isSelected: Boolean = false, type: MDSSelectionType = MDSSelectionType.PRIMARY, - onClick: () -> Unit + onClick: () -> Unit = {} ) { - val backgroundColor = - if (isSelected) type.backgroundColor else unSelectedBackgroundColor - val contentColor = - if (isSelected) type.contentColor else unSelectedContentColor - val borderColor = - if (isSelected) type.backgroundColor else Gray03 + val backgroundColor = selectionBackgroundColor(enabled, isSelected, type) + val contentColor = selectionContentColor(enabled, isSelected, type) + val borderColor = selectionBorderColor(enabled, isSelected, type) Box( modifier = modifier .clip(RoundedCornerShape(8.dp)) .background(color = backgroundColor) - .clickable { onClick() } + .clickable(enabled = enabled) { onClick() } .border( width = 1.dp, color = borderColor, @@ -59,28 +62,35 @@ fun MDSSelection( @Preview(showBackground = true) @Composable private fun MDSSelectionPreview() { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(10.dp) + var selectedType by remember { mutableIntStateOf(1) } + + Box( + modifier = Modifier + .fillMaxSize() + .background(Color.White) ) { - MDSSelection( - modifier = Modifier.weight(1f), - text = "동아리", - isSelected = true, - onClick = {} - ) - MDSSelection( - modifier = Modifier.weight(1f), - text = "나는 Secondary", - isSelected = true, - type = MDSSelectionType.SECONDARY, - onClick = {} - ) - MDSSelection( - modifier = Modifier.weight(1f), - text = "학생회", - isSelected = false, - onClick = {} - ) + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(10.dp) + ) { + MDSSelection( + modifier = Modifier.weight(1f), + text = "동아리", + isSelected = selectedType == 1, + onClick = { selectedType = 1 } + ) + MDSSelection( + modifier = Modifier.weight(1f), + text = "나는 Secondary", + isSelected = selectedType == 2, + type = MDSSelectionType.SECONDARY, + onClick = { selectedType = 2 } + ) + MDSSelection( + modifier = Modifier.weight(1f), + text = "나는 disabled", + enabled = false, + ) + } } } \ No newline at end of file diff --git a/core/design-system/src/main/java/com/moneymong/moneymong/design_system/component/selection/SelectionDefaults.kt b/core/design-system/src/main/java/com/moneymong/moneymong/design_system/component/selection/SelectionDefaults.kt new file mode 100644 index 00000000..c310238b --- /dev/null +++ b/core/design-system/src/main/java/com/moneymong/moneymong/design_system/component/selection/SelectionDefaults.kt @@ -0,0 +1,66 @@ +package com.moneymong.moneymong.design_system.component.selection + +import androidx.compose.ui.graphics.Color +import com.moneymong.moneymong.design_system.theme.Blue01 +import com.moneymong.moneymong.design_system.theme.Blue04 +import com.moneymong.moneymong.design_system.theme.Gray03 +import com.moneymong.moneymong.design_system.theme.Gray04 +import com.moneymong.moneymong.design_system.theme.Gray05 +import com.moneymong.moneymong.design_system.theme.White + + +enum class MDSSelectionType( + val backgroundColor: Color, + val contentColor: Color +) { + PRIMARY( + backgroundColor = Blue04, + contentColor = White + ), + SECONDARY( + backgroundColor = Blue01, + contentColor = Blue04 + ) +} + +internal val unSelectedBackgroundColor = White +internal val unSelectedContentColor = Gray05 + +internal val disabledBackgroundColor = Gray03 +internal val disabledContentColor = Gray04 + +internal val selectionBackgroundColor: ( + enabled: Boolean, + isSelected: Boolean, + type: MDSSelectionType +) -> Color = { enabled, isSelected, type -> + when { + enabled.not() -> disabledBackgroundColor + isSelected.not() -> unSelectedBackgroundColor + else -> type.backgroundColor + } +} + +internal val selectionContentColor: ( + enabled: Boolean, + isSelected: Boolean, + type: MDSSelectionType +) -> Color = { enabled, isSelected, type -> + when { + enabled.not() -> disabledContentColor + isSelected.not() -> unSelectedContentColor + else -> type.contentColor + } +} + +internal val selectionBorderColor: ( + enabled: Boolean, + isSelected: Boolean, + type: MDSSelectionType +) -> Color = { enabled, isSelected, type -> + when { + enabled.not() -> disabledBackgroundColor + isSelected.not() -> Gray03 + else -> type.backgroundColor + } +} \ No newline at end of file diff --git a/core/design-system/src/main/java/com/moneymong/moneymong/design_system/component/selection/SelectionType.kt b/core/design-system/src/main/java/com/moneymong/moneymong/design_system/component/selection/SelectionType.kt deleted file mode 100644 index 6b308d7f..00000000 --- a/core/design-system/src/main/java/com/moneymong/moneymong/design_system/component/selection/SelectionType.kt +++ /dev/null @@ -1,25 +0,0 @@ -package com.moneymong.moneymong.design_system.component.selection - -import androidx.compose.ui.graphics.Color -import com.moneymong.moneymong.design_system.theme.Blue01 -import com.moneymong.moneymong.design_system.theme.Blue04 -import com.moneymong.moneymong.design_system.theme.Gray05 -import com.moneymong.moneymong.design_system.theme.White - - -enum class MDSSelectionType( - val backgroundColor: Color, - val contentColor: Color -) { - PRIMARY( - backgroundColor = Blue04, - contentColor = White - ), - SECONDARY( - backgroundColor = Blue01, - contentColor = Blue04 - ), -} - -internal val unSelectedBackgroundColor = White -internal val unSelectedContentColor = Gray05 \ No newline at end of file From 8f48362b07bf3aa668342c1baf05ecd5d34feb0f Mon Sep 17 00:00:00 2001 From: jhg3410 Date: Thu, 25 Jul 2024 16:42:05 +0900 Subject: [PATCH 06/15] =?UTF-8?q?MONEYMONG-494=20feat:=20=EC=86=8C?= =?UTF-8?q?=EC=86=8D=20=ED=83=80=EC=9E=85=EC=97=90=20'=EA=B8=B0=ED=83=80?= =?UTF-8?q?=20=EB=AA=A8=EC=9E=84'=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../view/AgencyRegisterContentView.kt | 26 ++++++++++++++++--- .../moneymong/feature/agency/search/Agency.kt | 24 ++++++++++------- 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/register/view/AgencyRegisterContentView.kt b/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/register/view/AgencyRegisterContentView.kt index 4e2af5a7..749c5166 100644 --- a/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/register/view/AgencyRegisterContentView.kt +++ b/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/register/view/AgencyRegisterContentView.kt @@ -20,6 +20,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.focus.onFocusChanged import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.text.input.TextFieldValue +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.moneymong.moneymong.design_system.component.selection.MDSSelection import com.moneymong.moneymong.design_system.component.textfield.MDSTextField @@ -59,7 +60,7 @@ internal fun AgencyResisterContentView( @Composable private fun TitleView() { Text( - text = "동아리 or 학생회 등록에\n필요한 항목들을 채워주세요.", + text = "회비 관리가 필요한\n소속 정보를 알려주세요!", color = Gray10, style = Heading2 ) @@ -83,16 +84,22 @@ private fun SelectTypeView( ) { MDSSelection( modifier = Modifier.weight(1f), - text = "동아리", + text = AgencyType.CLUB.text, isSelected = agencyType == AgencyType.CLUB, onClick = { onAgencyTypeChange(AgencyType.CLUB) } ) MDSSelection( modifier = Modifier.weight(1f), - text = "학생회", + text = AgencyType.COUNCIL.text, isSelected = agencyType == AgencyType.COUNCIL, onClick = { onAgencyTypeChange(AgencyType.COUNCIL) } ) + MDSSelection( + modifier = Modifier.weight(1f), + text = AgencyType.GENERAL.text, + isSelected = agencyType == AgencyType.GENERAL, + onClick = { onAgencyTypeChange(AgencyType.GENERAL) } + ) } } } @@ -144,4 +151,17 @@ private fun InputNameView( focusManager.clearFocus() }) ) +} + + +@Preview +@Composable +private fun AgencyResisterContentViewPreview() { + AgencyResisterContentView( + agencyType = AgencyType.GENERAL, + onAgencyTypeChange = {}, + agencyName = TextFieldValue("동아리"), + onAgencyNameChange = {}, + changeNameTextFieldIsError = {} + ) } \ No newline at end of file diff --git a/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/Agency.kt b/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/Agency.kt index 594479fe..97faed69 100644 --- a/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/Agency.kt +++ b/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/Agency.kt @@ -10,12 +10,25 @@ data class Agency( val memberCount: Int ) +enum class AgencyType(val text: String) { + CLUB(text = "동아리"), + COUNCIL(text = "학생회"), + GENERAL(text = "기타 모임"); + + fun agencyRegisterTypeToString(): String = when (this) { + CLUB -> "IN_SCHOOL_CLUB" + COUNCIL -> "STUDENT_COUNCIL" + GENERAL -> "GENERAL" + } +} + fun AgencyGetResponse.toAgency(): Agency { return Agency( id = this.id, type = when (this.type) { "IN_SCHOOL_CLUB" -> AgencyType.CLUB "STUDENT_COUNCIL" -> AgencyType.COUNCIL + "GENERAL" -> AgencyType.GENERAL else -> throw IllegalArgumentException("Unknown type: $type") }, name = this.name, @@ -29,19 +42,10 @@ fun MyAgencyResponse.toAgency(): Agency { type = when (this.type) { "IN_SCHOOL_CLUB" -> AgencyType.CLUB "STUDENT_COUNCIL" -> AgencyType.COUNCIL + "GENERAL" -> AgencyType.GENERAL else -> throw IllegalArgumentException("Unknown type: $type") }, name = this.name, memberCount = this.headCount ) -} - -enum class AgencyType(val text: String) { - CLUB(text = "동아리"), - COUNCIL(text = "학생회"); - - fun agencyRegisterTypeToString(): String = when (this) { - CLUB -> "IN_SCHOOL_CLUB" - COUNCIL -> "STUDENT_COUNCIL" - } } \ No newline at end of file From b300d5fb63f0be411df7608fea563706ad1612af Mon Sep 17 00:00:00 2001 From: jhg3410 Date: Thu, 25 Jul 2024 16:59:28 +0900 Subject: [PATCH 07/15] =?UTF-8?q?MONEYMONG-494=20feat:=20=EB=8C=80?= =?UTF-8?q?=ED=95=99=20=EC=A0=95=EB=B3=B4=20=EC=9C=A0=EB=AC=B4=EB=A5=BC=20?= =?UTF-8?q?=EC=86=8C=EC=86=8D=20=EC=B0=BE=EA=B8=B0=20->=20=EC=86=8C?= =?UTF-8?q?=EC=86=8D=20=EB=93=B1=EB=A1=9D=EC=9C=BC=EB=A1=9C=20=EC=A0=84?= =?UTF-8?q?=EB=8B=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../agency/navigation/AgencyNavigation.kt | 2 +- .../navigation/AgencyRegisterNavigation.kt | 27 ++++++++++++++++--- .../agency/search/AgencySearchScreen.kt | 8 +++--- .../agency/search/AgencySearchSideEffect.kt | 2 +- .../agency/search/AgencySearchViewModel.kt | 3 ++- 5 files changed, 31 insertions(+), 11 deletions(-) diff --git a/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/navigation/AgencyNavigation.kt b/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/navigation/AgencyNavigation.kt index 740c4dc9..b8e29e87 100644 --- a/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/navigation/AgencyNavigation.kt +++ b/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/navigation/AgencyNavigation.kt @@ -19,7 +19,7 @@ fun NavController.navigateAgency( fun NavGraphBuilder.agencyScreen( padding: PaddingValues, - navigateToRegister: () -> Unit, + navigateToRegister: (isUniversityStudent: Boolean) -> Unit, navigateAgencyJoin: (agencyId: Long) -> Unit ) { composable(route = agencyRoute) { diff --git a/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/navigation/AgencyRegisterNavigation.kt b/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/navigation/AgencyRegisterNavigation.kt index cbabd184..36edc7b2 100644 --- a/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/navigation/AgencyRegisterNavigation.kt +++ b/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/navigation/AgencyRegisterNavigation.kt @@ -3,23 +3,42 @@ package com.moneymong.moneymong.feature.agency.navigation import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import androidx.navigation.NavOptions +import androidx.navigation.NavType import androidx.navigation.compose.composable +import androidx.navigation.navArgument import com.moneymong.moneymong.feature.agency.register.AgencyRegisterScreen const val agencyRegisterRoute = "agencyRegister_route" +const val IS_UNIVERSITY_STUDENT = "isUniversityStudent" +const val agencyRegisterRouteWithArgs = "${agencyRegisterRoute}/{${IS_UNIVERSITY_STUDENT}}" -fun NavController.navigateAgencyRegister(navOptions: NavOptions? = null) { - navigate(agencyRegisterRoute, navOptions) +private val arguments = listOf( + navArgument(IS_UNIVERSITY_STUDENT) { + type = NavType.BoolType + defaultValue = false + } +) + +fun NavController.navigateAgencyRegister( + isUniversityStudent: Boolean, + navOptions: NavOptions? = null +) { + navigate("${agencyRegisterRoute}/${isUniversityStudent}", navOptions) } fun NavGraphBuilder.agencyRegisterScreen( navigateToComplete: () -> Unit, navigateUp: () -> Unit ) { - composable(route = agencyRegisterRoute) { + composable( + route = agencyRegisterRouteWithArgs, + arguments = arguments + ) { backStackEntry -> AgencyRegisterScreen( navigateToComplete = navigateToComplete, - navigateUp = navigateUp + navigateUp = navigateUp, + registrableClubOrCouncil = backStackEntry.arguments?.getBoolean(IS_UNIVERSITY_STUDENT) + ?: false ) } } \ No newline at end of file diff --git a/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/AgencySearchScreen.kt b/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/AgencySearchScreen.kt index 12c01cc4..3c2f0051 100644 --- a/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/AgencySearchScreen.kt +++ b/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/AgencySearchScreen.kt @@ -29,13 +29,13 @@ import androidx.paging.compose.itemKey import com.moneymong.moneymong.common.error.MoneyMongError import com.moneymong.moneymong.design_system.R import com.moneymong.moneymong.design_system.component.button.MDSFloatingActionButton +import com.moneymong.moneymong.design_system.component.indicator.LoadingItem +import com.moneymong.moneymong.design_system.component.indicator.LoadingScreen import com.moneymong.moneymong.design_system.component.tooltip.MDSToolTip import com.moneymong.moneymong.design_system.component.tooltip.MDSToolTipPosition import com.moneymong.moneymong.design_system.error.ErrorDialog import com.moneymong.moneymong.design_system.error.ErrorItem import com.moneymong.moneymong.design_system.error.ErrorScreen -import com.moneymong.moneymong.design_system.component.indicator.LoadingItem -import com.moneymong.moneymong.design_system.component.indicator.LoadingScreen import com.moneymong.moneymong.design_system.theme.Body4 import com.moneymong.moneymong.design_system.theme.Gray01 import com.moneymong.moneymong.design_system.theme.Gray08 @@ -50,7 +50,7 @@ import org.orbitmvi.orbit.compose.collectSideEffect fun AgencySearchScreen( modifier: Modifier = Modifier, viewModel: AgencySearchViewModel = hiltViewModel(), - navigateToRegister: () -> Unit, + navigateToRegister: (isUniversityStudent: Boolean) -> Unit, navigateAgencyJoin: (agencyId: Long) -> Unit ) { val state by viewModel.collectAsState() @@ -59,7 +59,7 @@ fun AgencySearchScreen( viewModel.collectSideEffect { when (it) { is AgencySearchSideEffect.NavigateToRegister -> { - navigateToRegister() + navigateToRegister(it.isUniversityStudent) } is AgencySearchSideEffect.NavigateToAgencyJoin -> { diff --git a/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/AgencySearchSideEffect.kt b/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/AgencySearchSideEffect.kt index 678b673d..4934e6e8 100644 --- a/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/AgencySearchSideEffect.kt +++ b/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/AgencySearchSideEffect.kt @@ -3,6 +3,6 @@ package com.moneymong.moneymong.feature.agency.search import com.moneymong.moneymong.common.base.SideEffect sealed interface AgencySearchSideEffect : SideEffect { - data object NavigateToRegister : AgencySearchSideEffect + data class NavigateToRegister(val isUniversityStudent: Boolean) : AgencySearchSideEffect data class NavigateToAgencyJoin(val agencyId: Long) : AgencySearchSideEffect } \ No newline at end of file diff --git a/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/AgencySearchViewModel.kt b/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/AgencySearchViewModel.kt index 74869816..95a7fa3f 100644 --- a/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/AgencySearchViewModel.kt +++ b/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/AgencySearchViewModel.kt @@ -20,7 +20,8 @@ class AgencySearchViewModel @Inject constructor( ) : BaseViewModel(AgencySearchState()) { fun navigateToRegister() = - eventEmit(sideEffect = AgencySearchSideEffect.NavigateToRegister) + // todo: 서버 쪽에서 '대학 없음' 의 제공 방법이 나오면 교체 + eventEmit(sideEffect = AgencySearchSideEffect.NavigateToRegister(isUniversityStudent = false)) fun navigateToJoin(agencyId: Long) = eventEmit(sideEffect = AgencySearchSideEffect.NavigateToAgencyJoin(agencyId)) From 34af18b882c8e7eb1107989d7ba87c9db9131818 Mon Sep 17 00:00:00 2001 From: jhg3410 Date: Fri, 26 Jul 2024 20:29:03 +0900 Subject: [PATCH 08/15] =?UTF-8?q?MONEYMONG-494=20feat:=20=EB=8C=80?= =?UTF-8?q?=ED=95=99=20=EC=A0=95=EB=B3=B4=20=EC=9C=A0=EB=AC=B4=EC=97=90=20?= =?UTF-8?q?=EB=94=B0=EB=A5=B8=20=EB=93=B1=EB=A1=9D=20=EA=B0=80=EB=8A=A5?= =?UTF-8?q?=ED=95=9C=20=EC=86=8C=EC=86=8D=20=EC=A0=9C=ED=95=9C=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../agency/register/AgencyRegisterScreen.kt | 15 +++++++++++++-- .../register/view/AgencyRegisterContentView.kt | 16 +++++++++++----- .../moneymong/feature/agency/search/Agency.kt | 2 +- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/register/AgencyRegisterScreen.kt b/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/register/AgencyRegisterScreen.kt index 10c98b41..8e4a3fda 100644 --- a/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/register/AgencyRegisterScreen.kt +++ b/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/register/AgencyRegisterScreen.kt @@ -11,6 +11,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.material.Icon 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 @@ -34,6 +35,7 @@ import com.moneymong.moneymong.design_system.theme.Gray07 import com.moneymong.moneymong.design_system.theme.MMHorizontalSpacing import com.moneymong.moneymong.design_system.theme.White import com.moneymong.moneymong.feature.agency.register.view.AgencyResisterContentView +import com.moneymong.moneymong.feature.agency.search.AgencyType import org.orbitmvi.orbit.compose.collectAsState import org.orbitmvi.orbit.compose.collectSideEffect @@ -42,7 +44,8 @@ fun AgencyRegisterScreen( modifier: Modifier = Modifier, viewModel: AgencyRegisterViewModel = hiltViewModel(), navigateToComplete: () -> Unit, - navigateUp: () -> Unit + navigateUp: () -> Unit, + registrableClubOrCouncil: Boolean ) { val state by viewModel.collectAsState() val focusManager = LocalFocusManager.current @@ -60,6 +63,12 @@ fun AgencyRegisterScreen( } } + LaunchedEffect(key1 = registrableClubOrCouncil) { + if (registrableClubOrCouncil.not()) { + viewModel.changeAgencyType(AgencyType.GENERAL) + } + } + if (state.visibleOutDialog) { MDSModal( icon = R.drawable.ic_warning_filled, @@ -117,6 +126,7 @@ fun AgencyRegisterScreen( agencyName = state.agencyName, onAgencyNameChange = viewModel::changeAgencyName, changeNameTextFieldIsError = viewModel::changeNameTextFieldIsError, + registrableClubOrCouncil = registrableClubOrCouncil ) val canRegister = state.agencyName.text.isNotEmpty() && state.nameTextFieldIsError.not() @@ -137,6 +147,7 @@ fun AgencyRegisterScreen( fun AgencyRegisterScreenPreview() { AgencyRegisterScreen( navigateToComplete = {}, - navigateUp = {} + navigateUp = {}, + registrableClubOrCouncil = false ) } \ No newline at end of file diff --git a/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/register/view/AgencyRegisterContentView.kt b/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/register/view/AgencyRegisterContentView.kt index 749c5166..ef9dce22 100644 --- a/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/register/view/AgencyRegisterContentView.kt +++ b/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/register/view/AgencyRegisterContentView.kt @@ -38,14 +38,16 @@ internal fun AgencyResisterContentView( onAgencyTypeChange: (AgencyType) -> Unit, agencyName: TextFieldValue, onAgencyNameChange: (TextFieldValue) -> Unit, - changeNameTextFieldIsError: (Boolean) -> Unit + changeNameTextFieldIsError: (Boolean) -> Unit, + registrableClubOrCouncil: Boolean ) { Column(modifier = modifier) { TitleView() Spacer(modifier = Modifier.height(44.dp)) SelectTypeView( agencyType = agencyType, - onAgencyTypeChange = onAgencyTypeChange + onAgencyTypeChange = onAgencyTypeChange, + registrableClubOrCouncil = registrableClubOrCouncil ) Spacer(modifier = Modifier.height(24.dp)) InputNameView( @@ -70,7 +72,8 @@ private fun TitleView() { @Composable private fun SelectTypeView( agencyType: AgencyType?, - onAgencyTypeChange: (AgencyType) -> Unit + onAgencyTypeChange: (AgencyType) -> Unit, + registrableClubOrCouncil: Boolean ) { Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { Text( @@ -85,19 +88,21 @@ private fun SelectTypeView( MDSSelection( modifier = Modifier.weight(1f), text = AgencyType.CLUB.text, + enabled = registrableClubOrCouncil, isSelected = agencyType == AgencyType.CLUB, onClick = { onAgencyTypeChange(AgencyType.CLUB) } ) MDSSelection( modifier = Modifier.weight(1f), text = AgencyType.COUNCIL.text, + enabled = registrableClubOrCouncil, isSelected = agencyType == AgencyType.COUNCIL, onClick = { onAgencyTypeChange(AgencyType.COUNCIL) } ) MDSSelection( modifier = Modifier.weight(1f), text = AgencyType.GENERAL.text, - isSelected = agencyType == AgencyType.GENERAL, + isSelected = agencyType == AgencyType.GENERAL || registrableClubOrCouncil.not(), onClick = { onAgencyTypeChange(AgencyType.GENERAL) } ) } @@ -162,6 +167,7 @@ private fun AgencyResisterContentViewPreview() { onAgencyTypeChange = {}, agencyName = TextFieldValue("동아리"), onAgencyNameChange = {}, - changeNameTextFieldIsError = {} + changeNameTextFieldIsError = {}, + registrableClubOrCouncil = true ) } \ No newline at end of file diff --git a/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/Agency.kt b/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/Agency.kt index 97faed69..eed95827 100644 --- a/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/Agency.kt +++ b/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/Agency.kt @@ -18,7 +18,7 @@ enum class AgencyType(val text: String) { fun agencyRegisterTypeToString(): String = when (this) { CLUB -> "IN_SCHOOL_CLUB" COUNCIL -> "STUDENT_COUNCIL" - GENERAL -> "GENERAL" + GENERAL -> "GENERAL" // todo: 서버 쪽에서 '대학 없음' 을 받는 방법이 나오면 교체 } } From 09c4668327cb49176108f8112750170ef3500169 Mon Sep 17 00:00:00 2001 From: jhg3410 Date: Mon, 29 Jul 2024 22:05:48 +0900 Subject: [PATCH 09/15] =?UTF-8?q?MONEYMONG-494=20feat:=20=EB=82=B4=20?= =?UTF-8?q?=EB=8C=80=ED=95=99=20=EC=A0=95=EB=B3=B4=20=EA=B0=80=EC=A0=B8?= =?UTF-8?q?=EC=98=A4=EA=B8=B0=20api=20=ED=86=B5=EC=8B=A0=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20=EB=B0=8F=20University=20=EA=B4=80=EB=A0=A8=20UseCa?= =?UTF-8?q?se=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../moneymong/network/api/UniversityApi.kt | 4 +++ .../datasource/signup/UnivRemoteDataSource.kt | 7 +++-- .../signup/UnivRemoteDataSourceImpl.kt | 10 +++++-- .../repository/signup/UnivRepositoryImpl.kt | 5 ++++ .../domain/repository/UnivRepository.kt | 7 +++-- .../university/CreateUniveristyUseCase.kt | 13 ++++++++++ .../university/FetchMyUniversityUseCase.kt | 13 ++++++++++ .../SearchUniversityUseCase.kt} | 11 +++----- .../feature/sign/viewmodel/SignUpViewModel.kt | 26 ++++++++++--------- 9 files changed, 70 insertions(+), 26 deletions(-) create mode 100644 domain/src/main/java/com/moneymong/moneymong/domain/usecase/university/CreateUniveristyUseCase.kt create mode 100644 domain/src/main/java/com/moneymong/moneymong/domain/usecase/university/FetchMyUniversityUseCase.kt rename domain/src/main/java/com/moneymong/moneymong/domain/usecase/{signup/UnivUseCase.kt => university/SearchUniversityUseCase.kt} (50%) diff --git a/core/network/src/main/java/com/moneymong/moneymong/network/api/UniversityApi.kt b/core/network/src/main/java/com/moneymong/moneymong/network/api/UniversityApi.kt index bc68e2ce..9dcb60b7 100644 --- a/core/network/src/main/java/com/moneymong/moneymong/network/api/UniversityApi.kt +++ b/core/network/src/main/java/com/moneymong/moneymong/network/api/UniversityApi.kt @@ -1,6 +1,7 @@ package com.moneymong.moneymong.network.api import com.moneymong.moneymong.model.sign.UnivRequest +import com.moneymong.moneymong.model.sign.UnivResponse import com.moneymong.moneymong.model.sign.UniversitiesResponse import retrofit2.http.Body import retrofit2.http.GET @@ -18,4 +19,7 @@ interface UniversityApi { suspend fun searchUniv( @Query("keyword") searchQuery: String ): Result + + @GET("api/v1/user-university") + suspend fun getMyUniv(): Result } \ No newline at end of file diff --git a/data/src/main/java/com/moneymong/moneymong/data/datasource/signup/UnivRemoteDataSource.kt b/data/src/main/java/com/moneymong/moneymong/data/datasource/signup/UnivRemoteDataSource.kt index 3d59f394..915bce95 100644 --- a/data/src/main/java/com/moneymong/moneymong/data/datasource/signup/UnivRemoteDataSource.kt +++ b/data/src/main/java/com/moneymong/moneymong/data/datasource/signup/UnivRemoteDataSource.kt @@ -2,10 +2,13 @@ package com.moneymong.moneymong.data.datasource.signup import com.moneymong.moneymong.model.sign.SearchQueryRequest import com.moneymong.moneymong.model.sign.UnivRequest +import com.moneymong.moneymong.model.sign.UnivResponse import com.moneymong.moneymong.model.sign.UniversitiesResponse interface UnivRemoteDataSource { - suspend fun createUniv(body: UnivRequest) : Result + suspend fun createUniv(body: UnivRequest): Result - suspend fun searchUniv(searchQuery : SearchQueryRequest) : Result + suspend fun searchUniv(searchQuery: SearchQueryRequest): Result + + suspend fun getMyUniv(): Result } \ No newline at end of file diff --git a/data/src/main/java/com/moneymong/moneymong/data/datasource/signup/UnivRemoteDataSourceImpl.kt b/data/src/main/java/com/moneymong/moneymong/data/datasource/signup/UnivRemoteDataSourceImpl.kt index 534d35b7..fce6e293 100644 --- a/data/src/main/java/com/moneymong/moneymong/data/datasource/signup/UnivRemoteDataSourceImpl.kt +++ b/data/src/main/java/com/moneymong/moneymong/data/datasource/signup/UnivRemoteDataSourceImpl.kt @@ -1,12 +1,14 @@ package com.moneymong.moneymong.data.datasource.signup -import com.moneymong.moneymong.network.api.UniversityApi import com.moneymong.moneymong.model.sign.SearchQueryRequest import com.moneymong.moneymong.model.sign.UnivRequest +import com.moneymong.moneymong.model.sign.UnivResponse import com.moneymong.moneymong.model.sign.UniversitiesResponse +import com.moneymong.moneymong.network.api.UniversityApi import javax.inject.Inject -class UnivRemoteDataSourceImpl @Inject constructor(private val universityApi: UniversityApi) : UnivRemoteDataSource { +class UnivRemoteDataSourceImpl @Inject constructor(private val universityApi: UniversityApi) : + UnivRemoteDataSource { override suspend fun createUniv(body: UnivRequest): Result { return universityApi.createUniv(body = body) } @@ -14,4 +16,8 @@ class UnivRemoteDataSourceImpl @Inject constructor(private val universityApi: Un override suspend fun searchUniv(searchQuery: SearchQueryRequest): Result { return universityApi.searchUniv(searchQuery.searchQuery) } + + override suspend fun getMyUniv(): Result { + return universityApi.getMyUniv() + } } \ No newline at end of file diff --git a/data/src/main/java/com/moneymong/moneymong/data/repository/signup/UnivRepositoryImpl.kt b/data/src/main/java/com/moneymong/moneymong/data/repository/signup/UnivRepositoryImpl.kt index 202c42f8..7c5fb33d 100644 --- a/data/src/main/java/com/moneymong/moneymong/data/repository/signup/UnivRepositoryImpl.kt +++ b/data/src/main/java/com/moneymong/moneymong/data/repository/signup/UnivRepositoryImpl.kt @@ -4,6 +4,7 @@ import com.moneymong.moneymong.data.datasource.signup.UnivRemoteDataSource import com.moneymong.moneymong.domain.repository.UnivRepository import com.moneymong.moneymong.model.sign.SearchQueryRequest import com.moneymong.moneymong.model.sign.UnivRequest +import com.moneymong.moneymong.model.sign.UnivResponse import com.moneymong.moneymong.model.sign.UniversitiesResponse import javax.inject.Inject @@ -17,4 +18,8 @@ class UnivRepositoryImpl @Inject constructor( override suspend fun searchUniv(searchQuery: SearchQueryRequest): Result { return univRemoteDataSource.searchUniv(searchQuery) } + + override suspend fun getMyUniv(): Result { + return univRemoteDataSource.getMyUniv() + } } \ No newline at end of file diff --git a/domain/src/main/java/com/moneymong/moneymong/domain/repository/UnivRepository.kt b/domain/src/main/java/com/moneymong/moneymong/domain/repository/UnivRepository.kt index 62559313..fadba50c 100644 --- a/domain/src/main/java/com/moneymong/moneymong/domain/repository/UnivRepository.kt +++ b/domain/src/main/java/com/moneymong/moneymong/domain/repository/UnivRepository.kt @@ -2,10 +2,13 @@ package com.moneymong.moneymong.domain.repository import com.moneymong.moneymong.model.sign.SearchQueryRequest import com.moneymong.moneymong.model.sign.UnivRequest +import com.moneymong.moneymong.model.sign.UnivResponse import com.moneymong.moneymong.model.sign.UniversitiesResponse interface UnivRepository { - suspend fun createUniv(body: UnivRequest) : Result + suspend fun createUniv(body: UnivRequest): Result - suspend fun searchUniv(searchQuery: SearchQueryRequest) : Result + suspend fun searchUniv(searchQuery: SearchQueryRequest): Result + + suspend fun getMyUniv(): Result } \ No newline at end of file diff --git a/domain/src/main/java/com/moneymong/moneymong/domain/usecase/university/CreateUniveristyUseCase.kt b/domain/src/main/java/com/moneymong/moneymong/domain/usecase/university/CreateUniveristyUseCase.kt new file mode 100644 index 00000000..6e474301 --- /dev/null +++ b/domain/src/main/java/com/moneymong/moneymong/domain/usecase/university/CreateUniveristyUseCase.kt @@ -0,0 +1,13 @@ +package com.moneymong.moneymong.domain.usecase.university + +import com.moneymong.moneymong.domain.repository.UnivRepository +import com.moneymong.moneymong.model.sign.UnivRequest +import javax.inject.Inject + +class CreateUniversityUseCase @Inject constructor( + private val univRepository: UnivRepository +) { + suspend operator fun invoke(body: UnivRequest): Result { + return univRepository.createUniv(body) + } +} \ No newline at end of file diff --git a/domain/src/main/java/com/moneymong/moneymong/domain/usecase/university/FetchMyUniversityUseCase.kt b/domain/src/main/java/com/moneymong/moneymong/domain/usecase/university/FetchMyUniversityUseCase.kt new file mode 100644 index 00000000..e4145337 --- /dev/null +++ b/domain/src/main/java/com/moneymong/moneymong/domain/usecase/university/FetchMyUniversityUseCase.kt @@ -0,0 +1,13 @@ +package com.moneymong.moneymong.domain.usecase.university + +import com.moneymong.moneymong.domain.repository.UnivRepository +import com.moneymong.moneymong.model.sign.UnivResponse +import javax.inject.Inject + +class FetchMyUniversityUseCase @Inject constructor( + private val univRepository: UnivRepository +) { + suspend operator fun invoke(): Result { + return univRepository.getMyUniv() + } +} \ No newline at end of file diff --git a/domain/src/main/java/com/moneymong/moneymong/domain/usecase/signup/UnivUseCase.kt b/domain/src/main/java/com/moneymong/moneymong/domain/usecase/university/SearchUniversityUseCase.kt similarity index 50% rename from domain/src/main/java/com/moneymong/moneymong/domain/usecase/signup/UnivUseCase.kt rename to domain/src/main/java/com/moneymong/moneymong/domain/usecase/university/SearchUniversityUseCase.kt index bc5143fc..2247bc43 100644 --- a/domain/src/main/java/com/moneymong/moneymong/domain/usecase/signup/UnivUseCase.kt +++ b/domain/src/main/java/com/moneymong/moneymong/domain/usecase/university/SearchUniversityUseCase.kt @@ -1,19 +1,14 @@ -package com.moneymong.moneymong.domain.usecase.signup +package com.moneymong.moneymong.domain.usecase.university import com.moneymong.moneymong.domain.repository.UnivRepository import com.moneymong.moneymong.model.sign.SearchQueryRequest -import com.moneymong.moneymong.model.sign.UnivRequest import com.moneymong.moneymong.model.sign.UniversitiesResponse import javax.inject.Inject -class UnivUseCase @Inject constructor( +class SearchUniversityUseCase @Inject constructor( private val univRepository: UnivRepository ) { - suspend fun createUniv(body : UnivRequest) : Result{ - return univRepository.createUniv(body) - } - - suspend fun searchUniv(searchQuery : String) : Result { + suspend operator fun invoke(searchQuery: String): Result { return univRepository.searchUniv(SearchQueryRequest(searchQuery)) } } \ No newline at end of file diff --git a/feature/sign/src/main/java/com/moneymong/moneymong/feature/sign/viewmodel/SignUpViewModel.kt b/feature/sign/src/main/java/com/moneymong/moneymong/feature/sign/viewmodel/SignUpViewModel.kt index 5ccca470..50b26444 100644 --- a/feature/sign/src/main/java/com/moneymong/moneymong/feature/sign/viewmodel/SignUpViewModel.kt +++ b/feature/sign/src/main/java/com/moneymong/moneymong/feature/sign/viewmodel/SignUpViewModel.kt @@ -3,7 +3,8 @@ package com.moneymong.moneymong.feature.sign.viewmodel import androidx.compose.ui.text.input.TextFieldValue import com.moneymong.moneymong.common.base.BaseViewModel import com.moneymong.moneymong.domain.usecase.signup.SchoolInfoUseCase -import com.moneymong.moneymong.domain.usecase.signup.UnivUseCase +import com.moneymong.moneymong.domain.usecase.university.CreateUniversityUseCase +import com.moneymong.moneymong.domain.usecase.university.SearchUniversityUseCase import com.moneymong.moneymong.feature.sign.sideeffect.SignUpSideEffect import com.moneymong.moneymong.feature.sign.state.SignUpState import com.moneymong.moneymong.feature.sign.util.Grade @@ -20,12 +21,13 @@ import javax.inject.Inject @HiltViewModel class SignUpViewModel @Inject constructor( - private val univUseCase: UnivUseCase, - private val schoolInfoUseCase : SchoolInfoUseCase, + private val createUniversityUseCase: CreateUniversityUseCase, + private val searchUniversityUseCase: SearchUniversityUseCase, + private val schoolInfoUseCase: SchoolInfoUseCase, ) : BaseViewModel(SignUpState()) { fun createUniv(universityName: String, grade: Int) = intent { val body = UnivRequest(universityName, grade) - univUseCase.createUniv(body) + createUniversityUseCase(body) .onSuccess { reduce { state.copy( @@ -44,7 +46,7 @@ class SignUpViewModel @Inject constructor( } fun searchUniv(searchQuery: String) = intent { - univUseCase.searchUniv(searchQuery) + searchUniversityUseCase(searchQuery) .onSuccess { reduce { state.copy( @@ -61,7 +63,7 @@ class SignUpViewModel @Inject constructor( } } - fun storeSchoolInfoExist(infoExist : Boolean ){ + fun storeSchoolInfoExist(infoExist: Boolean) { CoroutineScope(Dispatchers.IO).launch { schoolInfoUseCase.invoke(infoExist) } @@ -149,16 +151,16 @@ class SignUpViewModel @Inject constructor( } } - fun visiblePopUpErrorChanged(visiblePopUpError : Boolean) = intent{ - reduce{ + fun visiblePopUpErrorChanged(visiblePopUpError: Boolean) = intent { + reduce { state.copy( visiblePopUpError = visiblePopUpError, ) } } - fun visibleErrorChanged(visibleError : Boolean) = intent{ - reduce{ + fun visibleErrorChanged(visibleError: Boolean) = intent { + reduce { state.copy( visibleError = visibleError, ) @@ -166,8 +168,8 @@ class SignUpViewModel @Inject constructor( } - fun isButtonVisibleChanged(isButtonVisible : Boolean) = intent{ - reduce{ + fun isButtonVisibleChanged(isButtonVisible: Boolean) = intent { + reduce { state.copy( isButtonVisible = isButtonVisible ) From 2b2987317b5c08b2dc9cb35d28ea7961733c59d5 Mon Sep 17 00:00:00 2001 From: jhg3410 Date: Mon, 29 Jul 2024 22:09:27 +0900 Subject: [PATCH 10/15] =?UTF-8?q?MONEYMONG-494=20feat:=20=EC=86=8C?= =?UTF-8?q?=EC=86=8D=20=EA=B2=80=EC=83=89=20=ED=99=94=EB=A9=B4=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EB=8C=80=ED=95=99=20=EC=A0=95=EB=B3=B4=20=EC=9C=A0?= =?UTF-8?q?=EB=AC=B4=20=ED=8C=90=EB=8B=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../agency/search/AgencySearchScreen.kt | 6 +-- .../agency/search/AgencySearchState.kt | 1 + .../agency/search/AgencySearchViewModel.kt | 46 +++++++++++++------ 3 files changed, 36 insertions(+), 17 deletions(-) diff --git a/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/AgencySearchScreen.kt b/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/AgencySearchScreen.kt index 3c2f0051..8796ae61 100644 --- a/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/AgencySearchScreen.kt +++ b/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/AgencySearchScreen.kt @@ -102,7 +102,7 @@ fun AgencySearchScreen( isLoading = state.isLoading, isError = state.isError, errorMessage = state.errorMessage, - fetchMyAgencyList = viewModel::fetchMyAgencyList + onRetry = viewModel::getInitialData, ) } Column( @@ -135,7 +135,7 @@ private fun AgencySearchContentView( isLoading: Boolean, isError: Boolean, errorMessage: String, - fetchMyAgencyList: () -> Unit + onRetry: () -> Unit, ) { val contentLoading = pagingItems.loadState.refresh is LoadState.Loading || isLoading val contentError = pagingItems.loadState.refresh is LoadState.Error || isError @@ -152,7 +152,7 @@ private fun AgencySearchContentView( message = contentErrorMessage, onRetry = { pagingItems.retry() - fetchMyAgencyList() + onRetry() }, ) } else { diff --git a/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/AgencySearchState.kt b/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/AgencySearchState.kt index 8ee355c3..2feee998 100644 --- a/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/AgencySearchState.kt +++ b/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/AgencySearchState.kt @@ -8,6 +8,7 @@ data class AgencySearchState( val isError: Boolean = false, val errorMessage: String = "", val visibleWarningDialog: Boolean = false, + val isUniversityStudent: Boolean = false ) : State { val joinedAgenciesIds: List diff --git a/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/AgencySearchViewModel.kt b/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/AgencySearchViewModel.kt index 95a7fa3f..9d5a7cec 100644 --- a/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/AgencySearchViewModel.kt +++ b/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/AgencySearchViewModel.kt @@ -7,21 +7,26 @@ import com.moneymong.moneymong.common.base.BaseViewModel import com.moneymong.moneymong.common.error.MoneyMongError import com.moneymong.moneymong.domain.usecase.agency.FetchMyAgencyListUseCase import com.moneymong.moneymong.domain.usecase.agency.GetAgenciesUseCase +import com.moneymong.moneymong.domain.usecase.university.FetchMyUniversityUseCase import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.async +import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.map import org.orbitmvi.orbit.syntax.simple.intent +import org.orbitmvi.orbit.syntax.simple.postSideEffect import org.orbitmvi.orbit.syntax.simple.reduce import javax.inject.Inject @HiltViewModel class AgencySearchViewModel @Inject constructor( getAgenciesUseCase: GetAgenciesUseCase, - private val fetchMyAgencyListUseCase: FetchMyAgencyListUseCase + private val fetchMyAgencyListUseCase: FetchMyAgencyListUseCase, + private val fetchMyUniversityUseCase: FetchMyUniversityUseCase ) : BaseViewModel(AgencySearchState()) { - fun navigateToRegister() = - // todo: 서버 쪽에서 '대학 없음' 의 제공 방법이 나오면 교체 - eventEmit(sideEffect = AgencySearchSideEffect.NavigateToRegister(isUniversityStudent = false)) + fun navigateToRegister() = intent { + postSideEffect(AgencySearchSideEffect.NavigateToRegister(isUniversityStudent = state.isUniversityStudent)) + } fun navigateToJoin(agencyId: Long) = eventEmit(sideEffect = AgencySearchSideEffect.NavigateToAgencyJoin(agencyId)) @@ -33,37 +38,50 @@ class AgencySearchViewModel @Inject constructor( }.cachedIn(viewModelScope) init { - fetchMyAgencyList() + getInitialData() } - fun fetchMyAgencyList() = intent { + fun getInitialData() = intent { reduce { state.copy( isLoading = true, isError = false ) } - fetchMyAgencyListUseCase() - .also { - reduce { state.copy(isLoading = false) } + coroutineScope { + val fetchMyAgenciesDeferred = async { + fetchMyAgencyListUseCase() + } + val fetchMyUniversityDeferred = async { + fetchMyUniversityUseCase() } - .onSuccess { + + val fetchMyUniversityResult = fetchMyUniversityDeferred.await() + val fetchMyAgenciesResult = fetchMyAgenciesDeferred.await() + + if (fetchMyAgenciesResult.isSuccess && fetchMyUniversityResult.isSuccess) { reduce { state.copy( - joinedAgencies = it.map { myAgencyResponse -> myAgencyResponse.toAgency() } + isLoading = false, + joinedAgencies = fetchMyAgenciesResult.getOrThrow() + .map { myAgencyResponse -> myAgencyResponse.toAgency() }, + isUniversityStudent = fetchMyUniversityResult.getOrThrow().universityName == "대학 없음", ) } - }.onFailure { + } else { reduce { state.copy( + isLoading = false, isError = true, - errorMessage = it.message ?: MoneyMongError.UnExpectedError.message, + errorMessage = fetchMyAgenciesResult.exceptionOrNull()?.message + ?: fetchMyUniversityResult.exceptionOrNull()?.message + ?: MoneyMongError.UnExpectedError.message ) } } + } } - fun changeVisibleWarningDialog(visible: Boolean) = intent { reduce { state.copy(visibleWarningDialog = visible) From b29932f40de5ac14f3e9aa37e8a5de619f55b0ab Mon Sep 17 00:00:00 2001 From: jhg3410 Date: Wed, 31 Jul 2024 16:08:30 +0900 Subject: [PATCH 11/15] =?UTF-8?q?MONEYMONG-494=20fix:=20=EC=86=8C=EC=86=8D?= =?UTF-8?q?=20=EA=B2=80=EC=83=89=20=ED=99=94=EB=A9=B4,=20=EB=8C=80?= =?UTF-8?q?=ED=95=99=20=EC=A0=95=EB=B3=B4=20=EC=9C=A0=EB=AC=B4=20=ED=8C=90?= =?UTF-8?q?=EB=8B=A8=20=EA=B8=B0=EC=A4=80=20null=20=EB=A1=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/moneymong/moneymong/model/sign/UnivResponse.kt | 2 +- .../moneymong/moneymong/network/di/NetworkModule.kt | 10 +++++----- .../feature/agency/search/AgencySearchViewModel.kt | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/model/src/main/java/com/moneymong/moneymong/model/sign/UnivResponse.kt b/core/model/src/main/java/com/moneymong/moneymong/model/sign/UnivResponse.kt index 46dbf79f..6a098bd1 100644 --- a/core/model/src/main/java/com/moneymong/moneymong/model/sign/UnivResponse.kt +++ b/core/model/src/main/java/com/moneymong/moneymong/model/sign/UnivResponse.kt @@ -1,6 +1,6 @@ package com.moneymong.moneymong.model.sign data class UnivResponse( - val universityName: String, + val universityName: String?, val grade: Int ) \ No newline at end of file diff --git a/core/network/src/main/java/com/moneymong/moneymong/network/di/NetworkModule.kt b/core/network/src/main/java/com/moneymong/moneymong/network/di/NetworkModule.kt index c56ba0f8..683c179a 100644 --- a/core/network/src/main/java/com/moneymong/moneymong/network/di/NetworkModule.kt +++ b/core/network/src/main/java/com/moneymong/moneymong/network/di/NetworkModule.kt @@ -9,15 +9,15 @@ import com.google.gson.GsonBuilder import com.moneymong.moneymong.network.BuildConfig import com.moneymong.moneymong.network.adapter.ResultCallAdapterFactory import com.moneymong.moneymong.network.api.AccessTokenApi -import com.moneymong.moneymong.network.api.UniversityApi -import com.moneymong.moneymong.network.util.AuthInterceptor -import com.moneymong.moneymong.network.api.MoneyMongApi import com.moneymong.moneymong.network.api.AgencyApi import com.moneymong.moneymong.network.api.ClovaApi import com.moneymong.moneymong.network.api.LedgerApi import com.moneymong.moneymong.network.api.LedgerDetailApi import com.moneymong.moneymong.network.api.MemberApi +import com.moneymong.moneymong.network.api.MoneyMongApi +import com.moneymong.moneymong.network.api.UniversityApi import com.moneymong.moneymong.network.api.UserApi +import com.moneymong.moneymong.network.util.AuthInterceptor import com.moneymong.moneymong.network.util.MoneyMongTokenAuthenticator import dagger.Module import dagger.Provides @@ -97,7 +97,7 @@ object NetworkModule { addConverterFactory(GsonConverterFactory.create(gson)) addCallAdapterFactory(ResultCallAdapterFactory.create()) }.build() - + @Provides @Singleton @ClovaRetrofit @@ -112,7 +112,7 @@ object NetworkModule { @Provides fun provideMoneyMongApi(@MoneyMongRetrofit retrofit: Retrofit): MoneyMongApi = retrofit.create(MoneyMongApi::class.java) - + @Provides fun provideUnivApi(@MoneyMongRetrofit retrofit: Retrofit): UniversityApi = retrofit.create(UniversityApi::class.java) diff --git a/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/AgencySearchViewModel.kt b/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/AgencySearchViewModel.kt index 9d5a7cec..c27bcd1e 100644 --- a/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/AgencySearchViewModel.kt +++ b/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/AgencySearchViewModel.kt @@ -65,7 +65,7 @@ class AgencySearchViewModel @Inject constructor( isLoading = false, joinedAgencies = fetchMyAgenciesResult.getOrThrow() .map { myAgencyResponse -> myAgencyResponse.toAgency() }, - isUniversityStudent = fetchMyUniversityResult.getOrThrow().universityName == "대학 없음", + isUniversityStudent = fetchMyUniversityResult.getOrThrow().universityName != null, ) } } else { From 3fb5f9d71b1eb4270783f717f362a8683d9b2338 Mon Sep 17 00:00:00 2001 From: jhg3410 Date: Wed, 31 Jul 2024 17:15:29 +0900 Subject: [PATCH 12/15] =?UTF-8?q?MONEYMONG-494=20feat:=20=EB=B6=88?= =?UTF-8?q?=ED=95=84=EC=9A=94=ED=95=9C=20todo=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/moneymong/moneymong/feature/agency/search/Agency.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/Agency.kt b/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/Agency.kt index eed95827..97faed69 100644 --- a/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/Agency.kt +++ b/feature/agency/src/main/java/com/moneymong/moneymong/feature/agency/search/Agency.kt @@ -18,7 +18,7 @@ enum class AgencyType(val text: String) { fun agencyRegisterTypeToString(): String = when (this) { CLUB -> "IN_SCHOOL_CLUB" COUNCIL -> "STUDENT_COUNCIL" - GENERAL -> "GENERAL" // todo: 서버 쪽에서 '대학 없음' 을 받는 방법이 나오면 교체 + GENERAL -> "GENERAL" } } From 6b3ea3ffe756b9b77ccce9f18d9001b45025fbaa Mon Sep 17 00:00:00 2001 From: jhg3410 Date: Wed, 31 Jul 2024 16:28:36 +0900 Subject: [PATCH 13/15] =?UTF-8?q?MONEYMONG-495=20feat:=20=EB=A7=88?= =?UTF-8?q?=EC=9D=B4=EB=AA=BD=20=ED=95=99=EA=B5=90=20=EC=A0=95=EB=B3=B4?= =?UTF-8?q?=EA=B0=80=20=EC=97=86=EC=9D=84=20=EC=8B=9C,=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=EC=97=86=EC=9D=8C=20=ED=91=9C=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../feature/mymong/main/view/MyMongInfoView.kt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/feature/mymong/src/main/java/com/moneymong/moneymong/feature/mymong/main/view/MyMongInfoView.kt b/feature/mymong/src/main/java/com/moneymong/moneymong/feature/mymong/main/view/MyMongInfoView.kt index 11479c5f..2fd0696a 100644 --- a/feature/mymong/src/main/java/com/moneymong/moneymong/feature/mymong/main/view/MyMongInfoView.kt +++ b/feature/mymong/src/main/java/com/moneymong/moneymong/feature/mymong/main/view/MyMongInfoView.kt @@ -21,8 +21,8 @@ import androidx.compose.ui.draw.drawBehind import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import com.moneymong.moneymong.design_system.R -import com.moneymong.moneymong.design_system.error.ErrorItem import com.moneymong.moneymong.design_system.component.indicator.LoadingItem +import com.moneymong.moneymong.design_system.error.ErrorItem import com.moneymong.moneymong.design_system.theme.Blue04 import com.moneymong.moneymong.design_system.theme.Body2 import com.moneymong.moneymong.design_system.theme.Body3 @@ -126,6 +126,12 @@ fun UniversityInfo( university: String, grade: Int ) { + val universityInfoText = when { + university.isEmpty() -> "정보 없음" + grade == 5 -> "$university ${grade}학년 이상" + else -> "$university ${grade}학년" + } + Box( modifier = Modifier .fillMaxWidth() @@ -148,7 +154,7 @@ fun UniversityInfo( ) Spacer(modifier = Modifier.width(8.dp)) Text( - text = "$university $grade" + if (grade == 5) "학년 이상" else "학년", + text = universityInfoText, color = Gray08, style = Body4 ) From a2d1a457a4c43e9d9e4786b86f42177fd565a0ec Mon Sep 17 00:00:00 2001 From: jhg3410 Date: Wed, 31 Jul 2024 16:41:48 +0900 Subject: [PATCH 14/15] =?UTF-8?q?MONEYMONG-495=20feat:=20=EB=A7=88?= =?UTF-8?q?=EC=9D=B4=EB=AA=BD=20=ED=95=99=EA=B5=90=20=EC=A0=95=EB=B3=B4=20?= =?UTF-8?q?=EC=A4=91=EC=95=99=20=EC=A0=95=EB=A0=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../moneymong/feature/mymong/main/view/MyMongInfoView.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/feature/mymong/src/main/java/com/moneymong/moneymong/feature/mymong/main/view/MyMongInfoView.kt b/feature/mymong/src/main/java/com/moneymong/moneymong/feature/mymong/main/view/MyMongInfoView.kt index 2fd0696a..44312bf5 100644 --- a/feature/mymong/src/main/java/com/moneymong/moneymong/feature/mymong/main/view/MyMongInfoView.kt +++ b/feature/mymong/src/main/java/com/moneymong/moneymong/feature/mymong/main/view/MyMongInfoView.kt @@ -146,7 +146,9 @@ fun UniversityInfo( style = Body3 ) Spacer(modifier = Modifier.height(6.dp)) - Row { + Row( + verticalAlignment = Alignment.CenterVertically + ) { Image( modifier = Modifier.size(24.dp), painter = painterResource(id = R.drawable.img_university), From 6cf8100b844dbef7f5c8de860c87a30b8072159c Mon Sep 17 00:00:00 2001 From: jhg3410 Date: Wed, 31 Jul 2024 17:03:41 +0900 Subject: [PATCH 15/15] =?UTF-8?q?MONEYMONG-495=20feat:=20=EB=A7=88?= =?UTF-8?q?=EC=9D=B4=EB=AA=BD=20=EC=8A=A4=ED=81=AC=EB=A1=A4=20=EA=B0=80?= =?UTF-8?q?=EB=8A=A5=EC=84=B1=20=EB=B6=80=EC=97=AC=20=EB=B0=8F=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=EC=97=90=20"=EB=8B=98"=20suffix=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../moneymong/moneymong/feature/mymong/main/MyMongScreen.kt | 3 +++ .../moneymong/feature/mymong/main/view/MyMongInfoView.kt | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/feature/mymong/src/main/java/com/moneymong/moneymong/feature/mymong/main/MyMongScreen.kt b/feature/mymong/src/main/java/com/moneymong/moneymong/feature/mymong/main/MyMongScreen.kt index bf60302a..c4bb3f91 100644 --- a/feature/mymong/src/main/java/com/moneymong/moneymong/feature/mymong/main/MyMongScreen.kt +++ b/feature/mymong/src/main/java/com/moneymong/moneymong/feature/mymong/main/MyMongScreen.kt @@ -6,6 +6,8 @@ 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.rememberScrollState +import androidx.compose.foundation.verticalScroll import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment @@ -77,6 +79,7 @@ fun MyMongScreen( modifier = modifier .fillMaxSize() .background(color = Gray01) + .verticalScroll(state = rememberScrollState()) .padding(horizontal = MMHorizontalSpacing), ) { MyMongTopBar(modifier = Modifier.align(Alignment.CenterHorizontally)) diff --git a/feature/mymong/src/main/java/com/moneymong/moneymong/feature/mymong/main/view/MyMongInfoView.kt b/feature/mymong/src/main/java/com/moneymong/moneymong/feature/mymong/main/view/MyMongInfoView.kt index 44312bf5..e0e4e7c2 100644 --- a/feature/mymong/src/main/java/com/moneymong/moneymong/feature/mymong/main/view/MyMongInfoView.kt +++ b/feature/mymong/src/main/java/com/moneymong/moneymong/feature/mymong/main/view/MyMongInfoView.kt @@ -97,7 +97,7 @@ private fun Profile( Spacer(modifier = Modifier.width(16.dp)) Column { Text( - text = name, + text = name + "님", color = Gray10, style = Heading1 )