From 4f326093aca041429032d019f71434dcfc4c44dc Mon Sep 17 00:00:00 2001 From: Sangyoon Date: Fri, 7 Nov 2025 00:16:54 +0900 Subject: [PATCH 1/3] =?UTF-8?q?[FEAT]=20=EB=8C=80=EC=8B=9C=EB=B3=B4?= =?UTF-8?q?=EB=93=9C=20api=20=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dashboard/data/local/database/.gitkeep | 0 .../dashboard/data/local/preferences/.gitkeep | 0 .../feature/dashboard/data/mapper/.gitkeep | 0 .../dashboard/data/mapper/DashboardMappers.kt | 9 ++ .../dashboard/data/remote/api/.gitkeep | 0 .../dashboard/data/remote/api/DashboardApi.kt | 17 +++ .../dashboard/data/remote/dto/.gitkeep | 0 .../data/remote/dto/DashboardResponseDto.kt | 8 ++ .../remote/dto/WeeklySummaryResponseDto.kt | 7 + .../dashboard/data/repository/.gitkeep | 0 .../repository/DashboardRepositoryImpl.kt | 30 +++++ .../android/feature/dashboard/di/.gitkeep | 0 .../feature/dashboard/di/DashboardModules.kt | 26 ++++ .../feature/dashboard/domain/model/.gitkeep | 0 .../dashboard/domain/model/Dashboard.kt | 8 ++ .../dashboard/domain/model/WeeklySummary.kt | 7 + .../dashboard/domain/repository/.gitkeep | 0 .../domain/repository/DashboardRepository.kt | 9 ++ .../feature/dashboard/domain/usecase/.gitkeep | 0 .../domain/usecase/GetDashboardUseCase.kt | 11 ++ .../domain/usecase/WeeklySummaryUseCase.kt | 11 ++ .../feature/dashboard/ui/DashboardScreen.kt | 120 ++++++++++++++---- .../feature/dashboard/ui/DashboardUiState.kt | 6 +- .../dashboard/ui/DashboardViewModel.kt | 105 ++++++++++----- app/src/main/res/drawable/block.xml | 9 ++ app/src/main/res/drawable/car.xml | 9 ++ app/src/main/res/values/strings.xml | 9 +- 27 files changed, 344 insertions(+), 57 deletions(-) delete mode 100644 app/src/main/java/com/sampoom/android/feature/dashboard/data/local/database/.gitkeep delete mode 100644 app/src/main/java/com/sampoom/android/feature/dashboard/data/local/preferences/.gitkeep delete mode 100644 app/src/main/java/com/sampoom/android/feature/dashboard/data/mapper/.gitkeep create mode 100644 app/src/main/java/com/sampoom/android/feature/dashboard/data/mapper/DashboardMappers.kt delete mode 100644 app/src/main/java/com/sampoom/android/feature/dashboard/data/remote/api/.gitkeep create mode 100644 app/src/main/java/com/sampoom/android/feature/dashboard/data/remote/api/DashboardApi.kt delete mode 100644 app/src/main/java/com/sampoom/android/feature/dashboard/data/remote/dto/.gitkeep create mode 100644 app/src/main/java/com/sampoom/android/feature/dashboard/data/remote/dto/DashboardResponseDto.kt create mode 100644 app/src/main/java/com/sampoom/android/feature/dashboard/data/remote/dto/WeeklySummaryResponseDto.kt delete mode 100644 app/src/main/java/com/sampoom/android/feature/dashboard/data/repository/.gitkeep create mode 100644 app/src/main/java/com/sampoom/android/feature/dashboard/data/repository/DashboardRepositoryImpl.kt delete mode 100644 app/src/main/java/com/sampoom/android/feature/dashboard/di/.gitkeep create mode 100644 app/src/main/java/com/sampoom/android/feature/dashboard/di/DashboardModules.kt delete mode 100644 app/src/main/java/com/sampoom/android/feature/dashboard/domain/model/.gitkeep create mode 100644 app/src/main/java/com/sampoom/android/feature/dashboard/domain/model/Dashboard.kt create mode 100644 app/src/main/java/com/sampoom/android/feature/dashboard/domain/model/WeeklySummary.kt delete mode 100644 app/src/main/java/com/sampoom/android/feature/dashboard/domain/repository/.gitkeep create mode 100644 app/src/main/java/com/sampoom/android/feature/dashboard/domain/repository/DashboardRepository.kt delete mode 100644 app/src/main/java/com/sampoom/android/feature/dashboard/domain/usecase/.gitkeep create mode 100644 app/src/main/java/com/sampoom/android/feature/dashboard/domain/usecase/GetDashboardUseCase.kt create mode 100644 app/src/main/java/com/sampoom/android/feature/dashboard/domain/usecase/WeeklySummaryUseCase.kt create mode 100644 app/src/main/res/drawable/block.xml create mode 100644 app/src/main/res/drawable/car.xml diff --git a/app/src/main/java/com/sampoom/android/feature/dashboard/data/local/database/.gitkeep b/app/src/main/java/com/sampoom/android/feature/dashboard/data/local/database/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/app/src/main/java/com/sampoom/android/feature/dashboard/data/local/preferences/.gitkeep b/app/src/main/java/com/sampoom/android/feature/dashboard/data/local/preferences/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/app/src/main/java/com/sampoom/android/feature/dashboard/data/mapper/.gitkeep b/app/src/main/java/com/sampoom/android/feature/dashboard/data/mapper/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/app/src/main/java/com/sampoom/android/feature/dashboard/data/mapper/DashboardMappers.kt b/app/src/main/java/com/sampoom/android/feature/dashboard/data/mapper/DashboardMappers.kt new file mode 100644 index 0000000..830b38e --- /dev/null +++ b/app/src/main/java/com/sampoom/android/feature/dashboard/data/mapper/DashboardMappers.kt @@ -0,0 +1,9 @@ +package com.sampoom.android.feature.dashboard.data.mapper + +import com.sampoom.android.feature.dashboard.data.remote.dto.DashboardResponseDto +import com.sampoom.android.feature.dashboard.data.remote.dto.WeeklySummaryResponseDto +import com.sampoom.android.feature.dashboard.domain.model.Dashboard +import com.sampoom.android.feature.dashboard.domain.model.WeeklySummary + +fun DashboardResponseDto.toModel(): Dashboard = Dashboard(totalParts, outOfStockParts, lowStockParts, totalQuantity) +fun WeeklySummaryResponseDto.toModel(): WeeklySummary = WeeklySummary(inStockParts, outStockParts, weekPeriod) \ No newline at end of file diff --git a/app/src/main/java/com/sampoom/android/feature/dashboard/data/remote/api/.gitkeep b/app/src/main/java/com/sampoom/android/feature/dashboard/data/remote/api/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/app/src/main/java/com/sampoom/android/feature/dashboard/data/remote/api/DashboardApi.kt b/app/src/main/java/com/sampoom/android/feature/dashboard/data/remote/api/DashboardApi.kt new file mode 100644 index 0000000..fde49dc --- /dev/null +++ b/app/src/main/java/com/sampoom/android/feature/dashboard/data/remote/api/DashboardApi.kt @@ -0,0 +1,17 @@ +package com.sampoom.android.feature.dashboard.data.remote.api + +import com.sampoom.android.core.model.ApiResponse +import com.sampoom.android.feature.dashboard.data.remote.dto.DashboardResponseDto +import com.sampoom.android.feature.dashboard.data.remote.dto.WeeklySummaryResponseDto +import retrofit2.http.GET +import retrofit2.http.Path + +interface DashboardApi { + // 대시보드 조회 + @GET("agency/{agencyId}/dashboard") + suspend fun getDashboard(@Path("agencyId") agencyId: Long): ApiResponse + + // 주간 히스토리 조회 + @GET("agency/{agencyId}/weekly-summary") + suspend fun getWeeklySummary(@Path("agencyId") agencyId: Long): ApiResponse +} \ No newline at end of file diff --git a/app/src/main/java/com/sampoom/android/feature/dashboard/data/remote/dto/.gitkeep b/app/src/main/java/com/sampoom/android/feature/dashboard/data/remote/dto/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/app/src/main/java/com/sampoom/android/feature/dashboard/data/remote/dto/DashboardResponseDto.kt b/app/src/main/java/com/sampoom/android/feature/dashboard/data/remote/dto/DashboardResponseDto.kt new file mode 100644 index 0000000..54c0643 --- /dev/null +++ b/app/src/main/java/com/sampoom/android/feature/dashboard/data/remote/dto/DashboardResponseDto.kt @@ -0,0 +1,8 @@ +package com.sampoom.android.feature.dashboard.data.remote.dto + +data class DashboardResponseDto( + val totalParts: Long, + val outOfStockParts: Long, + val lowStockParts: Long, + val totalQuantity: Long +) diff --git a/app/src/main/java/com/sampoom/android/feature/dashboard/data/remote/dto/WeeklySummaryResponseDto.kt b/app/src/main/java/com/sampoom/android/feature/dashboard/data/remote/dto/WeeklySummaryResponseDto.kt new file mode 100644 index 0000000..2b4d4b9 --- /dev/null +++ b/app/src/main/java/com/sampoom/android/feature/dashboard/data/remote/dto/WeeklySummaryResponseDto.kt @@ -0,0 +1,7 @@ +package com.sampoom.android.feature.dashboard.data.remote.dto + +data class WeeklySummaryResponseDto( + val inStockParts: Long, + val outStockParts: Long, + val weekPeriod: String +) diff --git a/app/src/main/java/com/sampoom/android/feature/dashboard/data/repository/.gitkeep b/app/src/main/java/com/sampoom/android/feature/dashboard/data/repository/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/app/src/main/java/com/sampoom/android/feature/dashboard/data/repository/DashboardRepositoryImpl.kt b/app/src/main/java/com/sampoom/android/feature/dashboard/data/repository/DashboardRepositoryImpl.kt new file mode 100644 index 0000000..5f0f1d9 --- /dev/null +++ b/app/src/main/java/com/sampoom/android/feature/dashboard/data/repository/DashboardRepositoryImpl.kt @@ -0,0 +1,30 @@ +package com.sampoom.android.feature.dashboard.data.repository + +import com.sampoom.android.core.preferences.AuthPreferences +import com.sampoom.android.feature.dashboard.data.mapper.toModel +import com.sampoom.android.feature.dashboard.data.remote.api.DashboardApi +import com.sampoom.android.feature.dashboard.domain.model.Dashboard +import com.sampoom.android.feature.dashboard.domain.model.WeeklySummary +import com.sampoom.android.feature.dashboard.domain.repository.DashboardRepository +import javax.inject.Inject + +class DashboardRepositoryImpl @Inject constructor( + private val api: DashboardApi, + private val authPreferences: AuthPreferences +) : DashboardRepository { + override suspend fun getDashboard(): Result { + return runCatching { + val agencyId = authPreferences.getStoredUser()?.agencyId ?: throw Exception() + val dto = api.getDashboard(agencyId) + dto.data.toModel() + } + } + + override suspend fun getWeeklySummary(): Result { + return runCatching { + val agencyId = authPreferences.getStoredUser()?.agencyId ?: throw Exception() + val dto = api.getWeeklySummary(agencyId) + dto.data.toModel() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/sampoom/android/feature/dashboard/di/.gitkeep b/app/src/main/java/com/sampoom/android/feature/dashboard/di/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/app/src/main/java/com/sampoom/android/feature/dashboard/di/DashboardModules.kt b/app/src/main/java/com/sampoom/android/feature/dashboard/di/DashboardModules.kt new file mode 100644 index 0000000..597d466 --- /dev/null +++ b/app/src/main/java/com/sampoom/android/feature/dashboard/di/DashboardModules.kt @@ -0,0 +1,26 @@ +package com.sampoom.android.feature.dashboard.di + +import com.sampoom.android.feature.dashboard.data.remote.api.DashboardApi +import com.sampoom.android.feature.dashboard.data.repository.DashboardRepositoryImpl +import com.sampoom.android.feature.dashboard.domain.repository.DashboardRepository +import dagger.Binds +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import retrofit2.Retrofit +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +abstract class DashboardBinModule { + @Binds @Singleton + abstract fun bindDashboardRepository(impl: DashboardRepositoryImpl): DashboardRepository +} + +@Module +@InstallIn(SingletonComponent::class) +object DashboardModule { + @Provides @Singleton + fun provideDashboardApi(retrofit: Retrofit): DashboardApi = retrofit.create(DashboardApi::class.java) +} \ No newline at end of file diff --git a/app/src/main/java/com/sampoom/android/feature/dashboard/domain/model/.gitkeep b/app/src/main/java/com/sampoom/android/feature/dashboard/domain/model/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/app/src/main/java/com/sampoom/android/feature/dashboard/domain/model/Dashboard.kt b/app/src/main/java/com/sampoom/android/feature/dashboard/domain/model/Dashboard.kt new file mode 100644 index 0000000..12c75bd --- /dev/null +++ b/app/src/main/java/com/sampoom/android/feature/dashboard/domain/model/Dashboard.kt @@ -0,0 +1,8 @@ +package com.sampoom.android.feature.dashboard.domain.model + +data class Dashboard( + val totalParts: Long, + val outOfStockParts: Long, + val lowStockParts: Long, + val totalQuantity: Long +) diff --git a/app/src/main/java/com/sampoom/android/feature/dashboard/domain/model/WeeklySummary.kt b/app/src/main/java/com/sampoom/android/feature/dashboard/domain/model/WeeklySummary.kt new file mode 100644 index 0000000..e2b38ba --- /dev/null +++ b/app/src/main/java/com/sampoom/android/feature/dashboard/domain/model/WeeklySummary.kt @@ -0,0 +1,7 @@ +package com.sampoom.android.feature.dashboard.domain.model + +data class WeeklySummary( + val inStockParts: Long, + val outStockParts: Long, + val weekPeriod: String +) \ No newline at end of file diff --git a/app/src/main/java/com/sampoom/android/feature/dashboard/domain/repository/.gitkeep b/app/src/main/java/com/sampoom/android/feature/dashboard/domain/repository/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/app/src/main/java/com/sampoom/android/feature/dashboard/domain/repository/DashboardRepository.kt b/app/src/main/java/com/sampoom/android/feature/dashboard/domain/repository/DashboardRepository.kt new file mode 100644 index 0000000..f26b53a --- /dev/null +++ b/app/src/main/java/com/sampoom/android/feature/dashboard/domain/repository/DashboardRepository.kt @@ -0,0 +1,9 @@ +package com.sampoom.android.feature.dashboard.domain.repository + +import com.sampoom.android.feature.dashboard.domain.model.Dashboard +import com.sampoom.android.feature.dashboard.domain.model.WeeklySummary + +interface DashboardRepository { + suspend fun getDashboard(): Result + suspend fun getWeeklySummary(): Result +} \ No newline at end of file diff --git a/app/src/main/java/com/sampoom/android/feature/dashboard/domain/usecase/.gitkeep b/app/src/main/java/com/sampoom/android/feature/dashboard/domain/usecase/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/app/src/main/java/com/sampoom/android/feature/dashboard/domain/usecase/GetDashboardUseCase.kt b/app/src/main/java/com/sampoom/android/feature/dashboard/domain/usecase/GetDashboardUseCase.kt new file mode 100644 index 0000000..f19af0f --- /dev/null +++ b/app/src/main/java/com/sampoom/android/feature/dashboard/domain/usecase/GetDashboardUseCase.kt @@ -0,0 +1,11 @@ +package com.sampoom.android.feature.dashboard.domain.usecase + +import com.sampoom.android.feature.dashboard.domain.model.Dashboard +import com.sampoom.android.feature.dashboard.domain.repository.DashboardRepository +import javax.inject.Inject + +class GetDashboardUseCase @Inject constructor( + private val repository: DashboardRepository +) { + suspend operator fun invoke(): Result = repository.getDashboard() +} \ No newline at end of file diff --git a/app/src/main/java/com/sampoom/android/feature/dashboard/domain/usecase/WeeklySummaryUseCase.kt b/app/src/main/java/com/sampoom/android/feature/dashboard/domain/usecase/WeeklySummaryUseCase.kt new file mode 100644 index 0000000..51620c6 --- /dev/null +++ b/app/src/main/java/com/sampoom/android/feature/dashboard/domain/usecase/WeeklySummaryUseCase.kt @@ -0,0 +1,11 @@ +package com.sampoom.android.feature.dashboard.domain.usecase + +import com.sampoom.android.feature.dashboard.domain.model.WeeklySummary +import com.sampoom.android.feature.dashboard.domain.repository.DashboardRepository +import javax.inject.Inject + +class WeeklySummaryUseCase @Inject constructor( + private val repository: DashboardRepository +) { + suspend operator fun invoke(): Result = repository.getWeeklySummary() +} \ No newline at end of file diff --git a/app/src/main/java/com/sampoom/android/feature/dashboard/ui/DashboardScreen.kt b/app/src/main/java/com/sampoom/android/feature/dashboard/ui/DashboardScreen.kt index 096f645..7b34360 100644 --- a/app/src/main/java/com/sampoom/android/feature/dashboard/ui/DashboardScreen.kt +++ b/app/src/main/java/com/sampoom/android/feature/dashboard/ui/DashboardScreen.kt @@ -1,5 +1,6 @@ package com.sampoom.android.feature.dashboard.ui +import android.R.attr.onClick import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.border @@ -50,12 +51,16 @@ import com.sampoom.android.R import com.sampoom.android.core.model.UserPosition import com.sampoom.android.core.ui.component.EmptyContent import com.sampoom.android.core.ui.component.ErrorContent +import com.sampoom.android.core.ui.theme.FailRed import com.sampoom.android.feature.order.ui.OrderItem import com.sampoom.android.core.ui.theme.Main500 +import com.sampoom.android.core.ui.theme.SuccessGreen import com.sampoom.android.core.ui.theme.backgroundCardColor import com.sampoom.android.core.ui.theme.textColor import com.sampoom.android.core.ui.theme.textSecondaryColor import com.sampoom.android.feature.auth.domain.model.User +import com.sampoom.android.feature.dashboard.domain.model.Dashboard +import com.sampoom.android.feature.dashboard.domain.model.WeeklySummary import com.sampoom.android.feature.order.domain.model.Order @Composable @@ -159,11 +164,10 @@ fun DashboardScreen( ) { item { TitleSection(user) } - item { ButtonSection(isManager) } + item { ButtonSection(isManager, uiState.dashboard) } item { OrderListSection( - viewModel = viewModel, orderListPaged = orderListPaged, onNavigateOrderDetail = { order -> onNavigateOrderDetail(order) @@ -174,6 +178,12 @@ fun DashboardScreen( ) } + item { Spacer(Modifier.height(32.dp)) } + + item { + WeeklySummarySection(modifier = Modifier, weeklySummary = uiState.weeklySummary) + } + item { Spacer(Modifier.height(100.dp)) } } } @@ -225,7 +235,8 @@ fun TitleSection( @Composable fun ButtonSection( - isManager: Boolean + isManager: Boolean, + dashboard: Dashboard? ) { Column( modifier = Modifier @@ -248,48 +259,48 @@ fun ButtonSection( ) } - // 보유 부품, 진행중 주문 + // 총 부품, 품절 부품 Row( horizontalArrangement = Arrangement.spacedBy(16.dp) ) { ButtonCard( modifier = Modifier.weight(1f), - painter = painterResource(R.drawable.parts), - painterDescription = stringResource(R.string.dashboard_parts_on_hand), - text = 1234.toString(), // TODO : API 연동 - subText = stringResource(R.string.dashboard_parts_on_hand), + painter = painterResource(R.drawable.car), + painterDescription = stringResource(R.string.dashboard_parts_all), + text = (dashboard?.totalParts ?: 0L).toString(), + subText = stringResource(R.string.dashboard_parts_all), onClick = { } ) ButtonCard( modifier = Modifier.weight(1f), - painter = painterResource(R.drawable.orders), - painterDescription = stringResource(R.string.dashboard_parts_in_progress), - text = 23.toString(), // TODO : API 연동 - subText = stringResource(R.string.dashboard_parts_in_progress), + painter = painterResource(R.drawable.block), + painterDescription = stringResource(R.string.dashboard_parts_out_of_stock), + text = (dashboard?.outOfStockParts ?: 0L).toString(), + subText = stringResource(R.string.dashboard_parts_out_of_stock), onClick = { } ) } - // 부족 부품, 주문 금액 + // 부족 부품, 보유 부품 Row( horizontalArrangement = Arrangement.spacedBy(16.dp) ) { ButtonCard( modifier = Modifier.weight(1f), painter = painterResource(R.drawable.warning), - painterDescription = stringResource(R.string.dashboard_shortage_of_parts), - text = 19.toString(), // TODO : API 연동 - subText = stringResource(R.string.dashboard_shortage_of_parts), + painterDescription = stringResource(R.string.dashboard_parts_low_stock), + text = (dashboard?.lowStockParts ?: 0L).toString(), + subText = stringResource(R.string.dashboard_parts_low_stock), onClick = { } ) ButtonCard( modifier = Modifier.weight(1f), - painter = painterResource(R.drawable.money), - painterDescription = stringResource(R.string.dashboard_order_amount), - text = 4123200.toString(), // TODO : API 연동 - subText = stringResource(R.string.dashboard_order_amount), + painter = painterResource(R.drawable.parts), + painterDescription = stringResource(R.string.dashboard_parts_on_hand), + text = (dashboard?.totalQuantity ?: 0L).toString(), + subText = stringResource(R.string.dashboard_parts_on_hand), onClick = { } ) } @@ -349,12 +360,10 @@ fun ButtonCard( @Composable fun OrderListSection( - viewModel: DashboardViewModel, orderListPaged: LazyPagingItems, onNavigateOrderDetail: (Order) -> Unit, onNavigationOrder: () -> Unit ) { - Column( modifier = Modifier.fillMaxWidth() ) { @@ -441,4 +450,71 @@ fun OrderListSection( } } } +} + +@Composable +fun WeeklySummarySection( + modifier: Modifier, + weeklySummary: WeeklySummary? +) { + Card( + modifier = modifier + .fillMaxWidth(), + colors = CardDefaults.cardColors( + containerColor = backgroundCardColor() + ), + onClick = { }, + ) { + Column( + modifier = Modifier + .fillMaxWidth() + .padding(16.dp) + ) { + Text( + text = stringResource(R.string.dashboard_weekly_summary_title), + style = MaterialTheme.typography.headlineMedium, + fontWeight = FontWeight.Bold, + color = textColor() + ) + + Row( + modifier = Modifier.fillMaxWidth() + ) { + Column( + modifier = Modifier.weight(1f), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text( + text = (weeklySummary?.inStockParts ?: 0L).toString(), + style = MaterialTheme.typography.headlineMedium, + fontWeight = FontWeight.Bold, + color = SuccessGreen + ) + Text( + text = stringResource(R.string.dashboard_weekly_summary_in_stock), + style = MaterialTheme.typography.titleMedium, + fontWeight = FontWeight.Light, + color = textSecondaryColor() + ) + } + Column( + modifier = Modifier.weight(1f), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text( + text = (weeklySummary?.outStockParts ?: 0L).toString(), + style = MaterialTheme.typography.headlineMedium, + fontWeight = FontWeight.Bold, + color = FailRed + ) + Text( + text = stringResource(R.string.dashboard_weekly_summary_out_stock), + style = MaterialTheme.typography.titleMedium, + fontWeight = FontWeight.Light, + color = textSecondaryColor() + ) + } + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/sampoom/android/feature/dashboard/ui/DashboardUiState.kt b/app/src/main/java/com/sampoom/android/feature/dashboard/ui/DashboardUiState.kt index 91da8e1..e6583a9 100644 --- a/app/src/main/java/com/sampoom/android/feature/dashboard/ui/DashboardUiState.kt +++ b/app/src/main/java/com/sampoom/android/feature/dashboard/ui/DashboardUiState.kt @@ -1,9 +1,13 @@ package com.sampoom.android.feature.dashboard.ui +import com.sampoom.android.feature.dashboard.domain.model.Dashboard +import com.sampoom.android.feature.dashboard.domain.model.WeeklySummary import com.sampoom.android.feature.order.domain.model.Order data class DashboardUiState( val orderList: List = emptyList(), + val dashboard: Dashboard? = null, + val weeklySummary: WeeklySummary? = null, val dashboardLoading: Boolean = false, - val dashboardError: String? = null, + val dashboardError: String? = null ) \ No newline at end of file diff --git a/app/src/main/java/com/sampoom/android/feature/dashboard/ui/DashboardViewModel.kt b/app/src/main/java/com/sampoom/android/feature/dashboard/ui/DashboardViewModel.kt index 768d537..7afa497 100644 --- a/app/src/main/java/com/sampoom/android/feature/dashboard/ui/DashboardViewModel.kt +++ b/app/src/main/java/com/sampoom/android/feature/dashboard/ui/DashboardViewModel.kt @@ -4,9 +4,12 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import androidx.paging.PagingData import androidx.paging.cachedIn +import com.sampoom.android.core.network.serverMessageOrNull import com.sampoom.android.core.util.GlobalMessageHandler import com.sampoom.android.feature.auth.domain.model.User import com.sampoom.android.feature.auth.domain.usecase.GetStoredUserUseCase +import com.sampoom.android.feature.dashboard.domain.usecase.GetDashboardUseCase +import com.sampoom.android.feature.dashboard.domain.usecase.WeeklySummaryUseCase import com.sampoom.android.feature.order.domain.model.Order import com.sampoom.android.feature.order.domain.usecase.GetOrderUseCase import dagger.hilt.android.lifecycle.HiltViewModel @@ -14,6 +17,7 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import javax.inject.Inject @@ -21,7 +25,9 @@ import javax.inject.Inject class DashboardViewModel @Inject constructor( private val messageHandler: GlobalMessageHandler, private val getOrderListUseCase: GetOrderUseCase, - private val getStoredUserUseCase: GetStoredUserUseCase + private val getStoredUserUseCase: GetStoredUserUseCase, + private val getDashboardUseCase: GetDashboardUseCase, + private val getWeeklySummaryUseCase: WeeklySummaryUseCase ): ViewModel() { private companion object { @@ -38,13 +44,14 @@ class DashboardViewModel @Inject constructor( .cachedIn(viewModelScope) private var errorLabel: String = "" - private var loadJob: Job? = null fun bindLabel(error: String) { errorLabel = error } init { + loadDashboard() + loadWeeklySummary() viewModelScope.launch { _user.value = getStoredUserUseCase() } @@ -52,36 +59,72 @@ class DashboardViewModel @Inject constructor( fun onEvent(event: DashboardUiEvent) { when (event) { - is DashboardUiEvent.LoadDashboard -> {}//loadOrderList() - is DashboardUiEvent.RetryDashboard -> {}//loadOrderList() + is DashboardUiEvent.LoadDashboard -> { + loadDashboard() + loadWeeklySummary() + } + is DashboardUiEvent.RetryDashboard -> { + loadDashboard() + loadWeeklySummary() + } } } -// private fun loadOrderList() { -// if (loadJob?.isActive == true) return -// loadJob = viewModelScope.launch { -// _uiState.update { it.copy(dashboardLoading = true, dashboardError = null) } -// -// getOrderListUseCase() -// .onSuccess { orderList -> -// _uiState.update { -// it.copy( -// orderList = orderList.items.take(5), -// dashboardLoading = false, -// dashboardError = null -// ) -// } -// } -// .onFailure { throwable -> -// val backendMessage = throwable.serverMessageOrNull() -// _uiState.update { -// it.copy( -// dashboardLoading = false, -// dashboardError = backendMessage ?: (throwable.message ?: errorLabel) -// ) -// } -// } -// Log.d(TAG, "submit: ${_uiState.value}") -// } -// } + private fun loadDashboard() { + viewModelScope.launch { + _uiState.update { it.copy(dashboardLoading = true, dashboardError = null) } + + getDashboardUseCase() + .onSuccess { dashboard -> + _uiState.update { + it.copy( + dashboard = dashboard, + dashboardLoading = false, + dashboardError = null + ) + } + } + .onFailure { throwable -> + val backendMessage = throwable.serverMessageOrNull() + val error = backendMessage ?: (throwable.message ?: errorLabel) + messageHandler.showMessage(message = error, isError = true) + + _uiState.update { + it.copy( + dashboardLoading = false, + dashboardError = error + ) + } + } + } + } + + private fun loadWeeklySummary() { + viewModelScope.launch { + _uiState.update { it.copy(dashboardLoading = true, dashboardError = null) } + + getWeeklySummaryUseCase() + .onSuccess { weeklySummary -> + _uiState.update { + it.copy( + weeklySummary = weeklySummary, + dashboardLoading = false, + dashboardError = null + ) + } + } + .onFailure { throwable -> + val backendMessage = throwable.serverMessageOrNull() + val error = backendMessage ?: (throwable.message ?: errorLabel) + messageHandler.showMessage(message = error, isError = true) + + _uiState.update { + it.copy( + dashboardLoading = false, + dashboardError = error + ) + } + } + } + } } \ No newline at end of file diff --git a/app/src/main/res/drawable/block.xml b/app/src/main/res/drawable/block.xml new file mode 100644 index 0000000..2ce7fd6 --- /dev/null +++ b/app/src/main/res/drawable/block.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/car.xml b/app/src/main/res/drawable/car.xml new file mode 100644 index 0000000..f89b46b --- /dev/null +++ b/app/src/main/res/drawable/car.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 29599f8..1001f02 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -44,11 +44,14 @@ 님! 오늘도 효율적인 재고 관리를 시작해보세요. 직원 관리 + 총 부품 + 품절 부품 + 부족 부품 보유 부품 - 진행중 부품 - 부족 부품 - 주문 금액 최근 주문 + 이번 주 요약 + 입고 부품 + 출고 부품 부품조회 From 8cfecd36014501ed644467d05581572a67b50380 Mon Sep 17 00:00:00 2001 From: Sangyoon Date: Fri, 7 Nov 2025 13:38:16 +0900 Subject: [PATCH 2/3] =?UTF-8?q?[FIX]=20=EC=BD=94=EB=93=9C=20=EB=9E=98?= =?UTF-8?q?=EB=B9=97=20=EB=9D=BC=EB=B7=B0=20=EC=82=AC=ED=95=AD=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 --- .../android/feature/dashboard/ui/DashboardScreen.kt | 3 +-- .../android/feature/dashboard/ui/DashboardUiState.kt | 4 +++- .../android/feature/dashboard/ui/DashboardViewModel.kt | 10 +++++----- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/sampoom/android/feature/dashboard/ui/DashboardScreen.kt b/app/src/main/java/com/sampoom/android/feature/dashboard/ui/DashboardScreen.kt index 7b34360..ffb7936 100644 --- a/app/src/main/java/com/sampoom/android/feature/dashboard/ui/DashboardScreen.kt +++ b/app/src/main/java/com/sampoom/android/feature/dashboard/ui/DashboardScreen.kt @@ -1,6 +1,5 @@ package com.sampoom.android.feature.dashboard.ui -import android.R.attr.onClick import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.border @@ -52,7 +51,6 @@ import com.sampoom.android.core.model.UserPosition import com.sampoom.android.core.ui.component.EmptyContent import com.sampoom.android.core.ui.component.ErrorContent import com.sampoom.android.core.ui.theme.FailRed -import com.sampoom.android.feature.order.ui.OrderItem import com.sampoom.android.core.ui.theme.Main500 import com.sampoom.android.core.ui.theme.SuccessGreen import com.sampoom.android.core.ui.theme.backgroundCardColor @@ -62,6 +60,7 @@ import com.sampoom.android.feature.auth.domain.model.User import com.sampoom.android.feature.dashboard.domain.model.Dashboard import com.sampoom.android.feature.dashboard.domain.model.WeeklySummary import com.sampoom.android.feature.order.domain.model.Order +import com.sampoom.android.feature.order.ui.OrderItem @Composable fun DashboardScreen( diff --git a/app/src/main/java/com/sampoom/android/feature/dashboard/ui/DashboardUiState.kt b/app/src/main/java/com/sampoom/android/feature/dashboard/ui/DashboardUiState.kt index e6583a9..4986b22 100644 --- a/app/src/main/java/com/sampoom/android/feature/dashboard/ui/DashboardUiState.kt +++ b/app/src/main/java/com/sampoom/android/feature/dashboard/ui/DashboardUiState.kt @@ -9,5 +9,7 @@ data class DashboardUiState( val dashboard: Dashboard? = null, val weeklySummary: WeeklySummary? = null, val dashboardLoading: Boolean = false, - val dashboardError: String? = null + val dashboardError: String? = null, + val weeklySummaryLoading: Boolean = false, + val weeklySummaryError: String? = null, ) \ No newline at end of file diff --git a/app/src/main/java/com/sampoom/android/feature/dashboard/ui/DashboardViewModel.kt b/app/src/main/java/com/sampoom/android/feature/dashboard/ui/DashboardViewModel.kt index 7afa497..f0e6e4e 100644 --- a/app/src/main/java/com/sampoom/android/feature/dashboard/ui/DashboardViewModel.kt +++ b/app/src/main/java/com/sampoom/android/feature/dashboard/ui/DashboardViewModel.kt @@ -101,15 +101,15 @@ class DashboardViewModel @Inject constructor( private fun loadWeeklySummary() { viewModelScope.launch { - _uiState.update { it.copy(dashboardLoading = true, dashboardError = null) } + _uiState.update { it.copy(weeklySummaryLoading = true, weeklySummaryError = null) } getWeeklySummaryUseCase() .onSuccess { weeklySummary -> _uiState.update { it.copy( weeklySummary = weeklySummary, - dashboardLoading = false, - dashboardError = null + weeklySummaryLoading = false, + weeklySummaryError = null ) } } @@ -120,8 +120,8 @@ class DashboardViewModel @Inject constructor( _uiState.update { it.copy( - dashboardLoading = false, - dashboardError = error + weeklySummaryLoading = false, + weeklySummaryError = error ) } } From c050c319d06b2d8704a3ec96118ad9c4d4f4b453 Mon Sep 17 00:00:00 2001 From: Sangyoon Date: Fri, 7 Nov 2025 14:25:01 +0900 Subject: [PATCH 3/3] =?UTF-8?q?[FIX]=20=EC=BD=94=EB=93=9C=20=EB=9E=98?= =?UTF-8?q?=EB=B9=97=20=EB=9D=BC=EB=B7=B0=20=EC=82=AC=ED=95=AD=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 --- .../android/feature/dashboard/ui/DashboardScreen.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/sampoom/android/feature/dashboard/ui/DashboardScreen.kt b/app/src/main/java/com/sampoom/android/feature/dashboard/ui/DashboardScreen.kt index ffb7936..4971cc0 100644 --- a/app/src/main/java/com/sampoom/android/feature/dashboard/ui/DashboardScreen.kt +++ b/app/src/main/java/com/sampoom/android/feature/dashboard/ui/DashboardScreen.kt @@ -266,7 +266,7 @@ fun ButtonSection( modifier = Modifier.weight(1f), painter = painterResource(R.drawable.car), painterDescription = stringResource(R.string.dashboard_parts_all), - text = (dashboard?.totalParts ?: 0L).toString(), + text = (dashboard?.totalParts ?: stringResource(R.string.common_slash)).toString(), subText = stringResource(R.string.dashboard_parts_all), onClick = { } ) @@ -275,7 +275,7 @@ fun ButtonSection( modifier = Modifier.weight(1f), painter = painterResource(R.drawable.block), painterDescription = stringResource(R.string.dashboard_parts_out_of_stock), - text = (dashboard?.outOfStockParts ?: 0L).toString(), + text = (dashboard?.outOfStockParts ?: stringResource(R.string.common_slash)).toString(), subText = stringResource(R.string.dashboard_parts_out_of_stock), onClick = { } ) @@ -289,7 +289,7 @@ fun ButtonSection( modifier = Modifier.weight(1f), painter = painterResource(R.drawable.warning), painterDescription = stringResource(R.string.dashboard_parts_low_stock), - text = (dashboard?.lowStockParts ?: 0L).toString(), + text = (dashboard?.lowStockParts ?: stringResource(R.string.common_slash)).toString(), subText = stringResource(R.string.dashboard_parts_low_stock), onClick = { } ) @@ -298,7 +298,7 @@ fun ButtonSection( modifier = Modifier.weight(1f), painter = painterResource(R.drawable.parts), painterDescription = stringResource(R.string.dashboard_parts_on_hand), - text = (dashboard?.totalQuantity ?: 0L).toString(), + text = (dashboard?.totalQuantity ?: stringResource(R.string.common_slash)).toString(), subText = stringResource(R.string.dashboard_parts_on_hand), onClick = { } ) @@ -484,7 +484,7 @@ fun WeeklySummarySection( horizontalAlignment = Alignment.CenterHorizontally ) { Text( - text = (weeklySummary?.inStockParts ?: 0L).toString(), + text = (weeklySummary?.inStockParts ?: stringResource(R.string.common_slash)).toString(), style = MaterialTheme.typography.headlineMedium, fontWeight = FontWeight.Bold, color = SuccessGreen @@ -501,7 +501,7 @@ fun WeeklySummarySection( horizontalAlignment = Alignment.CenterHorizontally ) { Text( - text = (weeklySummary?.outStockParts ?: 0L).toString(), + text = (weeklySummary?.outStockParts ?: stringResource(R.string.common_slash)).toString(), style = MaterialTheme.typography.headlineMedium, fontWeight = FontWeight.Bold, color = FailRed