diff --git a/core/designsystem/src/main/java/com/susu/core/designsystem/component/searchbar/SusuSearchBar.kt b/core/designsystem/src/main/java/com/susu/core/designsystem/component/searchbar/SusuSearchBar.kt
index 9a74dd2e..15d2bad1 100644
--- a/core/designsystem/src/main/java/com/susu/core/designsystem/component/searchbar/SusuSearchBar.kt
+++ b/core/designsystem/src/main/java/com/susu/core/designsystem/component/searchbar/SusuSearchBar.kt
@@ -30,6 +30,7 @@ import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.susu.core.designsystem.R
+import com.susu.core.designsystem.component.button.ClearIconButton
import com.susu.core.designsystem.theme.Gray100
import com.susu.core.designsystem.theme.Gray20
import com.susu.core.designsystem.theme.Gray60
@@ -40,6 +41,7 @@ fun SusuSearchBar(
modifier: Modifier = Modifier,
value: String,
onValueChange: (String) -> Unit = {},
+ onClickClearIcon: () -> Unit = {},
maxLines: Int = 1,
minLines: Int = 1,
textColor: Color = Gray100,
@@ -94,6 +96,13 @@ fun SusuSearchBar(
)
}
}
+
+ if (value.isNotEmpty()) {
+ ClearIconButton(
+ iconSize = 24.dp,
+ onClick = onClickClearIcon,
+ )
+ }
}
},
)
@@ -104,7 +113,7 @@ fun SusuSearchBar(
fun SusuSearchBarPreview() {
SusuTheme {
var text by remember {
- mutableStateOf("")
+ mutableStateOf("zzzz")
}
SusuSearchBar(
diff --git a/core/model/src/main/java/com/susu/core/model/Category.kt b/core/model/src/main/java/com/susu/core/model/Category.kt
new file mode 100644
index 00000000..e35d01ed
--- /dev/null
+++ b/core/model/src/main/java/com/susu/core/model/Category.kt
@@ -0,0 +1,8 @@
+package com.susu.core.model
+
+data class Category(
+ val id: Int,
+ val seq: Int,
+ val category: String,
+ val customCategory: String? = null,
+)
diff --git a/core/model/src/main/java/com/susu/core/model/Ledger.kt b/core/model/src/main/java/com/susu/core/model/Ledger.kt
new file mode 100644
index 00000000..fced05c1
--- /dev/null
+++ b/core/model/src/main/java/com/susu/core/model/Ledger.kt
@@ -0,0 +1,15 @@
+package com.susu.core.model
+
+import androidx.compose.runtime.Stable
+import java.time.LocalDateTime
+
+@Stable
+data class Ledger(
+ val id: Int,
+ val title: String,
+ val description: String,
+ val startAt: LocalDateTime,
+ val endAt: LocalDateTime,
+ val category: Category,
+ val totalAmounts: Int,
+)
diff --git a/core/ui/src/main/res/values/strings.xml b/core/ui/src/main/res/values/strings.xml
index 19e91fa6..2d9826d0 100644
--- a/core/ui/src/main/res/values/strings.xml
+++ b/core/ui/src/main/res/values/strings.xml
@@ -5,6 +5,7 @@
금액 높은 순
금액 낮은 순
최근 검색
+ 검색 결과
편집
저장
삭제
diff --git a/data/src/main/java/com/susu/data/data/di/RepositoryModule.kt b/data/src/main/java/com/susu/data/data/di/RepositoryModule.kt
index a9b67d77..34902eb2 100644
--- a/data/src/main/java/com/susu/data/data/di/RepositoryModule.kt
+++ b/data/src/main/java/com/susu/data/data/di/RepositoryModule.kt
@@ -1,11 +1,13 @@
package com.susu.data.data.di
import com.susu.data.data.repository.LedgerRecentSearchRepositoryImpl
+import com.susu.data.data.repository.LedgerRepositoryImpl
import com.susu.data.data.repository.LoginRepositoryImpl
import com.susu.data.data.repository.SignUpRepositoryImpl
import com.susu.data.data.repository.TermRepositoryImpl
import com.susu.data.data.repository.TokenRepositoryImpl
import com.susu.domain.repository.LedgerRecentSearchRepository
+import com.susu.domain.repository.LedgerRepository
import com.susu.domain.repository.LoginRepository
import com.susu.domain.repository.SignUpRepository
import com.susu.domain.repository.TermRepository
@@ -43,4 +45,9 @@ abstract class RepositoryModule {
abstract fun bindTermRepository(
termRepositoryImpl: TermRepositoryImpl,
): TermRepository
+
+ @Binds
+ abstract fun bindLedgerRepository(
+ ledgerRepositoryImpl: LedgerRepositoryImpl,
+ ): LedgerRepository
}
diff --git a/data/src/main/java/com/susu/data/data/repository/LedgerRepositoryImpl.kt b/data/src/main/java/com/susu/data/data/repository/LedgerRepositoryImpl.kt
new file mode 100644
index 00000000..4f0e75df
--- /dev/null
+++ b/data/src/main/java/com/susu/data/data/repository/LedgerRepositoryImpl.kt
@@ -0,0 +1,31 @@
+package com.susu.data.data.repository
+
+import com.susu.core.model.Ledger
+import com.susu.data.remote.api.LedgerService
+import com.susu.data.remote.model.response.toModel
+import com.susu.domain.repository.LedgerRepository
+import kotlinx.datetime.toKotlinLocalDateTime
+import java.time.LocalDateTime
+import javax.inject.Inject
+
+class LedgerRepositoryImpl @Inject constructor(
+ private val ledgerService: LedgerService,
+) : LedgerRepository {
+ override suspend fun getLedgerList(
+ title: String?,
+ categoryId: Long?,
+ fromStartAt: LocalDateTime,
+ toEndAt: LocalDateTime,
+ page: Int?,
+ sort: String?,
+ ): List {
+ return ledgerService.getLedgerList(
+ title = title,
+ categoryId = categoryId,
+ fromStartAt = fromStartAt.toKotlinLocalDateTime(),
+ toEndAt = toEndAt.toKotlinLocalDateTime(),
+ page = page,
+ sort = sort,
+ ).getOrThrow().toModel()
+ }
+}
diff --git a/data/src/main/java/com/susu/data/remote/api/LedgerService.kt b/data/src/main/java/com/susu/data/remote/api/LedgerService.kt
new file mode 100644
index 00000000..e24872b9
--- /dev/null
+++ b/data/src/main/java/com/susu/data/remote/api/LedgerService.kt
@@ -0,0 +1,19 @@
+package com.susu.data.remote.api
+
+import com.susu.data.remote.model.response.LedgerListResponse
+import com.susu.data.remote.retrofit.ApiResult
+import kotlinx.datetime.LocalDateTime
+import retrofit2.http.GET
+import retrofit2.http.Query
+
+interface LedgerService {
+ @GET("ledgers")
+ suspend fun getLedgerList(
+ @Query("title") title: String?,
+ @Query("categoryId") categoryId: Long?,
+ @Query("fromStartAt") fromStartAt: LocalDateTime,
+ @Query("toEndAt") toEndAt: LocalDateTime,
+ @Query("page") page: Int?,
+ @Query("sort") sort: String?,
+ ): ApiResult
+}
diff --git a/data/src/main/java/com/susu/data/remote/di/ApiServiceModule.kt b/data/src/main/java/com/susu/data/remote/di/ApiServiceModule.kt
index 7ddec6cc..aa41241f 100644
--- a/data/src/main/java/com/susu/data/remote/di/ApiServiceModule.kt
+++ b/data/src/main/java/com/susu/data/remote/di/ApiServiceModule.kt
@@ -1,5 +1,6 @@
package com.susu.data.remote.di
+import com.susu.data.remote.api.LedgerService
import com.susu.data.remote.api.SignUpService
import com.susu.data.remote.api.TermService
import com.susu.data.remote.api.TokenService
@@ -39,4 +40,10 @@ object ApiServiceModule {
fun providesTermService(retrofit: Retrofit): TermService {
return retrofit.create(TermService::class.java)
}
+
+ @Singleton
+ @Provides
+ fun providesLedgerService(retrofit: Retrofit): LedgerService {
+ return retrofit.create(LedgerService::class.java)
+ }
}
diff --git a/data/src/main/java/com/susu/data/remote/model/response/LedgerListResponse.kt b/data/src/main/java/com/susu/data/remote/model/response/LedgerListResponse.kt
new file mode 100644
index 00000000..71eeb782
--- /dev/null
+++ b/data/src/main/java/com/susu/data/remote/model/response/LedgerListResponse.kt
@@ -0,0 +1,72 @@
+package com.susu.data.remote.model.response
+
+import com.susu.core.model.Category
+import kotlinx.datetime.LocalDateTime
+import kotlinx.datetime.toJavaLocalDateTime
+import kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class LedgerListResponse(
+ @SerialName("data")
+ val ledgerList: List,
+ val page: Int,
+ val size: Int,
+ val totalPage: Int,
+ val totalCount: Int,
+ val sort: SortInfo,
+)
+
+@Serializable
+data class Ledger(
+ @SerialName("ledger")
+ val info: LedgerInfo,
+ val category: CategoryInfo,
+ val totalAmounts: Int,
+ val totalCounts: Int,
+)
+
+@Serializable
+data class LedgerInfo(
+ val id: Int,
+ val title: String,
+ val description: String,
+ val startAt: LocalDateTime,
+ val endAt: LocalDateTime,
+)
+
+@Serializable
+data class CategoryInfo(
+ val id: Int,
+ val seq: Int,
+ val category: String,
+ val customCategory: String? = null,
+)
+
+@Serializable
+data class SortInfo(
+ val empty: Boolean,
+ val unsorted: Boolean,
+ val sorted: Boolean,
+)
+
+internal fun LedgerListResponse.toModel() = this.ledgerList.map { ledger ->
+ with(ledger) {
+ com.susu.core.model.Ledger(
+ id = info.id,
+ title = info.title,
+ description = info.description,
+ startAt = info.startAt.toJavaLocalDateTime(),
+ endAt = info.endAt.toJavaLocalDateTime(),
+ category = category.toModel(),
+ totalAmounts = totalAmounts,
+ )
+ }
+}
+
+internal fun CategoryInfo.toModel() = Category(
+ id = id,
+ seq = seq,
+ category = category,
+ customCategory = customCategory,
+)
diff --git a/domain/src/main/java/com/susu/domain/repository/LedgerRepository.kt b/domain/src/main/java/com/susu/domain/repository/LedgerRepository.kt
new file mode 100644
index 00000000..97602be5
--- /dev/null
+++ b/domain/src/main/java/com/susu/domain/repository/LedgerRepository.kt
@@ -0,0 +1,15 @@
+package com.susu.domain.repository
+
+import com.susu.core.model.Ledger
+import java.time.LocalDateTime
+
+interface LedgerRepository {
+ suspend fun getLedgerList(
+ title: String?,
+ categoryId: Long?,
+ fromStartAt: LocalDateTime,
+ toEndAt: LocalDateTime,
+ page: Int?,
+ sort: String?,
+ ): List
+}
diff --git a/domain/src/main/java/com/susu/domain/usecase/ledger/GetLedgerListUseCase.kt b/domain/src/main/java/com/susu/domain/usecase/ledger/GetLedgerListUseCase.kt
new file mode 100644
index 00000000..edb20111
--- /dev/null
+++ b/domain/src/main/java/com/susu/domain/usecase/ledger/GetLedgerListUseCase.kt
@@ -0,0 +1,32 @@
+package com.susu.domain.usecase.ledger
+
+import com.susu.core.common.runCatchingIgnoreCancelled
+import com.susu.domain.repository.LedgerRepository
+import java.time.LocalDateTime
+import javax.inject.Inject
+
+class GetLedgerListUseCase @Inject constructor(
+ private val ledgerRepository: LedgerRepository,
+) {
+ suspend operator fun invoke(param: Param) = runCatchingIgnoreCancelled {
+ with(param) {
+ ledgerRepository.getLedgerList(
+ title = title,
+ categoryId = categoryId,
+ fromStartAt = fromStartAt,
+ toEndAt = toEndAt,
+ page = page,
+ sort = sort,
+ )
+ }
+ }
+
+ data class Param(
+ val title: String? = null,
+ val categoryId: Long? = null,
+ val fromStartAt: LocalDateTime = LocalDateTime.now().minusYears(10),
+ val toEndAt: LocalDateTime = LocalDateTime.now(),
+ val page: Int? = null,
+ val sort: String? = null,
+ )
+}
diff --git a/feature/received/src/main/java/com/susu/feature/received/navigation/ReceivedNavigation.kt b/feature/received/src/main/java/com/susu/feature/received/navigation/ReceivedNavigation.kt
index b83df67b..867246b8 100644
--- a/feature/received/src/main/java/com/susu/feature/received/navigation/ReceivedNavigation.kt
+++ b/feature/received/src/main/java/com/susu/feature/received/navigation/ReceivedNavigation.kt
@@ -74,6 +74,7 @@ fun NavGraphBuilder.receivedNavGraph(
composable(route = ReceivedRoute.ledgerSearchRoute) {
LedgerSearchRoute(
popBackStack = popBackStack,
+ navigateLedgerDetail = navigateLedgerDetail,
)
}
composable(
diff --git a/feature/received/src/main/java/com/susu/feature/received/search/LedgerSearchContract.kt b/feature/received/src/main/java/com/susu/feature/received/search/LedgerSearchContract.kt
index 8033b589..f7a2e55d 100644
--- a/feature/received/src/main/java/com/susu/feature/received/search/LedgerSearchContract.kt
+++ b/feature/received/src/main/java/com/susu/feature/received/search/LedgerSearchContract.kt
@@ -1,5 +1,6 @@
package com.susu.feature.received.search
+import com.susu.core.model.Ledger
import com.susu.core.ui.base.SideEffect
import com.susu.core.ui.base.UiState
import kotlinx.collections.immutable.PersistentList
@@ -7,10 +8,13 @@ import kotlinx.collections.immutable.persistentListOf
data class LedgerSearchState(
val searchKeyword: String = "",
- val searchKeywordList: PersistentList = persistentListOf(),
+ val recentSearchKeywordList: PersistentList = persistentListOf(),
+ val ledgerList: PersistentList = persistentListOf(),
val isLoading: Boolean = false,
+ val showSearchResultEmpty: Boolean = false,
) : UiState
sealed interface LedgerSearchSideEffect : SideEffect {
data object PopBackStack : LedgerSearchSideEffect
+ data class NavigateLedgerDetail(val id: Int) : LedgerSearchSideEffect
}
diff --git a/feature/received/src/main/java/com/susu/feature/received/search/LedgerSearchScreen.kt b/feature/received/src/main/java/com/susu/feature/received/search/LedgerSearchScreen.kt
index c1a4e465..2d968a6e 100644
--- a/feature/received/src/main/java/com/susu/feature/received/search/LedgerSearchScreen.kt
+++ b/feature/received/src/main/java/com/susu/feature/received/search/LedgerSearchScreen.kt
@@ -1,5 +1,6 @@
package com.susu.feature.received.search
+import androidx.compose.animation.Crossfade
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
@@ -7,10 +8,10 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
@@ -26,19 +27,25 @@ import com.susu.core.designsystem.component.searchbar.SusuSearchBar
import com.susu.core.designsystem.theme.Gray60
import com.susu.core.designsystem.theme.Gray80
import com.susu.core.designsystem.theme.SusuTheme
+import com.susu.core.model.Ledger
import com.susu.core.ui.extension.collectWithLifecycle
import com.susu.feature.received.R
import kotlinx.collections.immutable.PersistentList
+import kotlinx.coroutines.FlowPreview
+import kotlinx.coroutines.flow.debounce
+@OptIn(FlowPreview::class)
@Composable
fun LedgerSearchRoute(
viewModel: LedgerSearchViewModel = hiltViewModel(),
popBackStack: () -> Unit,
+ navigateLedgerDetail: (Int) -> Unit,
) {
val uiState = viewModel.uiState.collectAsStateWithLifecycle().value
viewModel.sideEffect.collectWithLifecycle { sideEffect ->
when (sideEffect) {
LedgerSearchSideEffect.PopBackStack -> popBackStack()
+ is LedgerSearchSideEffect.NavigateLedgerDetail -> navigateLedgerDetail(sideEffect.id)
}
}
@@ -46,15 +53,25 @@ fun LedgerSearchRoute(
viewModel.getLedgerRecentSearchList()
}
+ LaunchedEffect(key1 = uiState.searchKeyword) {
+ snapshotFlow { uiState.searchKeyword }
+ .debounce(100L)
+ .collect(viewModel::getLedgerList)
+ }
+
LedgerSearchScreen(
uiState = uiState,
onClickBackIcon = viewModel::popBackStack,
onValueChangeSearchBar = viewModel::updateSearch,
- onClickRecentSearchContainer = viewModel::upsertLedgerRecentSearch,
+ onClickSearchClearIcon = { viewModel.updateSearch("") },
+ onClickRecentSearchContainer = { search ->
+ viewModel.updateSearch(search)
+ viewModel.upsertLedgerRecentSearch(search)
+ },
onClickRecentSearchContainerCloseIcon = viewModel::deleteLedgerRecentSearch,
- onSearchDone = {
- viewModel.upsertLedgerRecentSearch(it)
- viewModel.updateSearch("")
+ onClickSearchResultContainer = {
+ viewModel.upsertLedgerRecentSearch(it.title)
+ viewModel.navigateLedgerDetail(it.id)
},
)
}
@@ -63,10 +80,11 @@ fun LedgerSearchRoute(
fun LedgerSearchScreen(
uiState: LedgerSearchState = LedgerSearchState(),
onClickBackIcon: () -> Unit = {},
+ onClickSearchClearIcon: () -> Unit = {},
onValueChangeSearchBar: (String) -> Unit = {},
onClickRecentSearchContainer: (String) -> Unit = {},
onClickRecentSearchContainerCloseIcon: (String) -> Unit = {},
- onSearchDone: (String) -> Unit = {}, // TODO REMOVE -> 테스트 용
+ onClickSearchResultContainer: (Ledger) -> Unit = {},
) {
Box(
modifier = Modifier
@@ -90,23 +108,24 @@ fun LedgerSearchScreen(
SusuSearchBar(
value = uiState.searchKeyword,
onValueChange = onValueChangeSearchBar,
+ onClickClearIcon = onClickSearchClearIcon,
placeholder = stringResource(R.string.ledger_search_screen_search_placeholder),
- keyboardActions = KeyboardActions(
- onDone = {
- // TODO REMOVE -> 테스트 용
- onSearchDone(uiState.searchKeyword)
- },
- ),
)
- if (uiState.searchKeywordList.isEmpty()) {
- RecentSearchEmptyScreen()
- } else {
- RecentSearchScreen(
- recentSearchList = uiState.searchKeywordList,
- onClickItem = onClickRecentSearchContainer,
- onClickCloseIcon = onClickRecentSearchContainerCloseIcon,
- )
+ Crossfade(targetState = uiState.searchKeyword.isEmpty(), label = "SearchColumn") { showRecentSearch ->
+ if (showRecentSearch) {
+ RecentSearchColumn(
+ recentSearchList = uiState.recentSearchKeywordList,
+ onClickItem = onClickRecentSearchContainer,
+ onClickCloseIcon = onClickRecentSearchContainerCloseIcon,
+ )
+ } else {
+ SearchResultColumn(
+ showSearchResultEmpty = uiState.showSearchResultEmpty,
+ ledgerList = uiState.ledgerList,
+ onClickItem = onClickSearchResultContainer,
+ )
+ }
}
}
}
@@ -114,19 +133,21 @@ fun LedgerSearchScreen(
}
@Composable
-private fun RecentSearchEmptyScreen() {
+private fun ResultEmptyColumn(
+ title: String,
+) {
Column(
modifier = Modifier.fillMaxWidth().padding(top = 136.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(SusuTheme.spacing.spacing_xxxxs),
) {
Text(
- text = stringResource(R.string.ledger_search_screen_empty_recent_search_title),
+ text = title,
style = SusuTheme.typography.title_xs,
color = Gray80,
)
Text(
- text = stringResource(R.string.ledger_search_screen_empty_recent_search_description),
+ text = stringResource(R.string.ledger_search_screen_empty_search_description),
style = SusuTheme.typography.text_xxs,
textAlign = TextAlign.Center,
color = Gray80,
@@ -135,26 +156,63 @@ private fun RecentSearchEmptyScreen() {
}
@Composable
-private fun RecentSearchScreen(
+private fun RecentSearchColumn(
recentSearchList: PersistentList,
onClickItem: (String) -> Unit,
onClickCloseIcon: (String) -> Unit,
) {
- Column(
- modifier = Modifier.padding(top = SusuTheme.spacing.spacing_xxl),
- verticalArrangement = Arrangement.spacedBy(SusuTheme.spacing.spacing_m),
- ) {
- Text(
- text = stringResource(com.susu.core.ui.R.string.word_recent_search),
- style = SusuTheme.typography.title_xxs,
- color = Gray60,
+ if (recentSearchList.isEmpty()) {
+ ResultEmptyColumn(
+ title = stringResource(R.string.ledger_search_screen_empty_recent_search_title),
)
- recentSearchList.forEach { name ->
- SusuRecentSearchContainer(
- text = name,
- onClick = { onClickItem(name) },
- onClickCloseIcon = { onClickCloseIcon(name) },
+ } else {
+ Column(
+ modifier = Modifier.padding(top = SusuTheme.spacing.spacing_xxl),
+ verticalArrangement = Arrangement.spacedBy(SusuTheme.spacing.spacing_m),
+ ) {
+ Text(
+ text = stringResource(com.susu.core.ui.R.string.word_recent_search),
+ style = SusuTheme.typography.title_xxs,
+ color = Gray60,
)
+ recentSearchList.forEach { name ->
+ SusuRecentSearchContainer(
+ text = name,
+ onClick = { onClickItem(name) },
+ onClickCloseIcon = { onClickCloseIcon(name) },
+ )
+ }
+ }
+ }
+}
+
+@Composable
+private fun SearchResultColumn(
+ showSearchResultEmpty: Boolean,
+ ledgerList: PersistentList,
+ onClickItem: (Ledger) -> Unit,
+) {
+ if (showSearchResultEmpty) {
+ ResultEmptyColumn(
+ title = stringResource(R.string.ledger_search_screen_empty_search_result_title),
+ )
+ } else {
+ Column(
+ modifier = Modifier.padding(top = SusuTheme.spacing.spacing_xxl),
+ verticalArrangement = Arrangement.spacedBy(SusuTheme.spacing.spacing_m),
+ ) {
+ Text(
+ text = stringResource(com.susu.core.ui.R.string.word_search_result),
+ style = SusuTheme.typography.title_xxs,
+ color = Gray60,
+ )
+ ledgerList.forEach { ledger ->
+ SusuRecentSearchContainer(
+ typeIconId = R.drawable.ic_ledger,
+ text = ledger.title,
+ onClick = { onClickItem(ledger) },
+ )
+ }
}
}
}
diff --git a/feature/received/src/main/java/com/susu/feature/received/search/LedgerSearchViewModel.kt b/feature/received/src/main/java/com/susu/feature/received/search/LedgerSearchViewModel.kt
index 59ad5003..d8210429 100644
--- a/feature/received/src/main/java/com/susu/feature/received/search/LedgerSearchViewModel.kt
+++ b/feature/received/src/main/java/com/susu/feature/received/search/LedgerSearchViewModel.kt
@@ -2,6 +2,7 @@ package com.susu.feature.received.search
import androidx.lifecycle.viewModelScope
import com.susu.core.ui.base.BaseViewModel
+import com.susu.domain.usecase.ledger.GetLedgerListUseCase
import com.susu.domain.usecase.ledgerrecentsearch.DeleteLedgerRecentSearchUseCase
import com.susu.domain.usecase.ledgerrecentsearch.GetLedgerRecentSearchListUseCase
import com.susu.domain.usecase.ledgerrecentsearch.UpsertLedgerRecentSearchUseCase
@@ -15,9 +16,12 @@ class LedgerSearchViewModel @Inject constructor(
private val upsertLedgerRecentSearchUseCase: UpsertLedgerRecentSearchUseCase,
private val getLedgerRecentSearchListUseCase: GetLedgerRecentSearchListUseCase,
private val deleteLedgerRecentSearchUseCase: DeleteLedgerRecentSearchUseCase,
+ private val getLedgerListUseCase: GetLedgerListUseCase,
) : BaseViewModel(
LedgerSearchState(),
) {
+ fun navigateLedgerDetail(id: Int) = postSideEffect(LedgerSearchSideEffect.NavigateLedgerDetail(id))
+
fun getLedgerRecentSearchList() = viewModelScope.launch {
getLedgerRecentSearchListUseCase()
.onSuccess(::updateRecentSearchList)
@@ -38,7 +42,17 @@ class LedgerSearchViewModel @Inject constructor(
fun updateSearch(search: String) = intent { copy(searchKeyword = search) }
+ fun getLedgerList(search: String) = viewModelScope.launch {
+ getLedgerListUseCase(GetLedgerListUseCase.Param(title = search))
+ .onSuccess { intent { copy(ledgerList = it.toPersistentList()) } }
+ }
+
fun popBackStack() = postSideEffect(LedgerSearchSideEffect.PopBackStack)
- private fun updateRecentSearchList(searchList: List) = intent { copy(searchKeywordList = searchList.toPersistentList()) }
+ private fun updateRecentSearchList(searchList: List) = intent {
+ copy(
+ recentSearchKeywordList = searchList.toPersistentList(),
+ showSearchResultEmpty = searchList.isEmpty(),
+ )
+ }
}
diff --git a/feature/received/src/main/res/drawable/ic_ledger.xml b/feature/received/src/main/res/drawable/ic_ledger.xml
new file mode 100644
index 00000000..c58956bd
--- /dev/null
+++ b/feature/received/src/main/res/drawable/ic_ledger.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/feature/received/src/main/res/values/strings.xml b/feature/received/src/main/res/values/strings.xml
index 953a889e..cfdcf105 100644
--- a/feature/received/src/main/res/values/strings.xml
+++ b/feature/received/src/main/res/values/strings.xml
@@ -4,8 +4,9 @@
필터 아이콘
아직 받은 장부가 없어요
받아요
- 장부 이름, 경조사 카테고리 등을\n검색해볼 수 있어요
+ 장부 이름, 경조사 카테고리 등을\n검색해볼 수 있어요
어떤 장부를 찾아드릴까요?
+ 원하는 검색 결과가 없나요?
찾고 싶은 장부를 검색해보세요
아직 보낸 봉투가 없어요
받은 봉투 추가하기