diff --git a/app/src/main/java/com/hackathon/alddeul_babsang/app/di/DataSourceModule.kt b/app/src/main/java/com/hackathon/alddeul_babsang/app/di/DataSourceModule.kt index e071bad..fcdda97 100644 --- a/app/src/main/java/com/hackathon/alddeul_babsang/app/di/DataSourceModule.kt +++ b/app/src/main/java/com/hackathon/alddeul_babsang/app/di/DataSourceModule.kt @@ -5,12 +5,14 @@ import com.hackathon.alddeul_babsang.data.datasource.DetailDataSource import com.hackathon.alddeul_babsang.data.datasource.ExampleDataSource import com.hackathon.alddeul_babsang.data.datasource.MapDataSource import com.hackathon.alddeul_babsang.data.datasource.ProfileDataSource +import com.hackathon.alddeul_babsang.data.datasource.ReportDataSource import com.hackathon.alddeul_babsang.data.datasource.UserPreferencesDataSource import com.hackathon.alddeul_babsang.data.datasourceimpl.BabsangDataSourceImpl import com.hackathon.alddeul_babsang.data.datasourceimpl.DetailDataSourceImpl import com.hackathon.alddeul_babsang.data.datasourceimpl.ExampleDataSourceImpl import com.hackathon.alddeul_babsang.data.datasourceimpl.MapDataSourceImpl import com.hackathon.alddeul_babsang.data.datasourceimpl.ProfileDataSourceImpl +import com.hackathon.alddeul_babsang.data.datasourceimpl.ReportDataSourceImpl import com.hackathon.alddeul_babsang.data.datasourceimpl.UserPreferencesDataSourceImpl import dagger.Binds import dagger.Module @@ -45,4 +47,9 @@ abstract class DataSourceModule { @Binds @Singleton abstract fun bindMapDataSource(mapDataSourceImpl: MapDataSourceImpl): MapDataSource + + @Binds + @Singleton + abstract fun bindReportDataSource(reportDataSourceImpl: ReportDataSourceImpl): ReportDataSource + } \ No newline at end of file diff --git a/app/src/main/java/com/hackathon/alddeul_babsang/app/di/RepositoryModule.kt b/app/src/main/java/com/hackathon/alddeul_babsang/app/di/RepositoryModule.kt index 1f76552..c9fe71f 100644 --- a/app/src/main/java/com/hackathon/alddeul_babsang/app/di/RepositoryModule.kt +++ b/app/src/main/java/com/hackathon/alddeul_babsang/app/di/RepositoryModule.kt @@ -5,12 +5,14 @@ import com.hackathon.alddeul_babsang.data.repositoryimpl.DetailRepositoryImpl import com.hackathon.alddeul_babsang.data.repositoryimpl.ExampleRepositoryImpl import com.hackathon.alddeul_babsang.data.repositoryimpl.MapRepositoryImpl import com.hackathon.alddeul_babsang.data.repositoryimpl.ProfileRepositoryImpl +import com.hackathon.alddeul_babsang.data.repositoryimpl.ReportRepositoryImpl import com.hackathon.alddeul_babsang.data.repositoryimpl.UserPreferencesRepositoryImpl import com.hackathon.alddeul_babsang.domain.repository.BabsangRepository import com.hackathon.alddeul_babsang.domain.repository.DetailRepository import com.hackathon.alddeul_babsang.domain.repository.ExampleRepository import com.hackathon.alddeul_babsang.domain.repository.MapRepository import com.hackathon.alddeul_babsang.domain.repository.ProfileRepository +import com.hackathon.alddeul_babsang.domain.repository.ReportRepository import com.hackathon.alddeul_babsang.domain.repository.UserPreferencesRepository import dagger.Binds import dagger.Module @@ -42,6 +44,10 @@ abstract class RepositoryModule { @Singleton abstract fun bindDetailRepository(detailRepositoryImpl: DetailRepositoryImpl): DetailRepository + @Binds + @Singleton + abstract fun bindReportRepository(reportDataSourceImpl: ReportRepositoryImpl): ReportRepository + @Binds @Singleton abstract fun bindMapRepository(mapRepositoryImpl: MapRepositoryImpl): MapRepository diff --git a/app/src/main/java/com/hackathon/alddeul_babsang/app/di/ServiceModule.kt b/app/src/main/java/com/hackathon/alddeul_babsang/app/di/ServiceModule.kt index 048292c..8b43625 100644 --- a/app/src/main/java/com/hackathon/alddeul_babsang/app/di/ServiceModule.kt +++ b/app/src/main/java/com/hackathon/alddeul_babsang/app/di/ServiceModule.kt @@ -1,6 +1,7 @@ package com.hackathon.alddeul_babsang.app.di import com.hackathon.alddeul_babsang.data.service.BabsangApiService +import com.hackathon.alddeul_babsang.data.service.ReportApiService import com.hackathon.alddeul_babsang.data.service.DetailApiService import com.hackathon.alddeul_babsang.data.service.MapApiService import com.hackathon.alddeul_babsang.data.service.ProfileApiService @@ -45,4 +46,12 @@ object ServiceModule { fun provideMapService( @AlddeulRetrofit retrofit: Retrofit ): MapApiService = retrofit.create(MapApiService::class.java) + + @Provides + @Singleton + fun provideReportService( + @AlddeulRetrofit retrofit: Retrofit + ): ReportApiService = retrofit.create(ReportApiService::class.java) + + } diff --git a/app/src/main/java/com/hackathon/alddeul_babsang/data/datasource/ReportDataSource.kt b/app/src/main/java/com/hackathon/alddeul_babsang/data/datasource/ReportDataSource.kt new file mode 100644 index 0000000..fd7d62c --- /dev/null +++ b/app/src/main/java/com/hackathon/alddeul_babsang/data/datasource/ReportDataSource.kt @@ -0,0 +1,16 @@ +package com.hackathon.alddeul_babsang.data.datasource + +import com.hackathon.alddeul_babsang.data.dto.BaseResponse +import com.hackathon.alddeul_babsang.data.dto.request.RequestReportDto +import com.hackathon.alddeul_babsang.data.dto.request.RequestReportWriteDto +import com.hackathon.alddeul_babsang.data.dto.response.ResponseReportDto + +interface ReportDataSource { + suspend fun postReports( + userId: Int + ): BaseResponse> + + suspend fun postReportWrite( + requestReportWriteDto: RequestReportWriteDto + ): BaseResponse +} \ No newline at end of file diff --git a/app/src/main/java/com/hackathon/alddeul_babsang/data/datasourceimpl/ReportDataSourceImpl.kt b/app/src/main/java/com/hackathon/alddeul_babsang/data/datasourceimpl/ReportDataSourceImpl.kt new file mode 100644 index 0000000..c865a31 --- /dev/null +++ b/app/src/main/java/com/hackathon/alddeul_babsang/data/datasourceimpl/ReportDataSourceImpl.kt @@ -0,0 +1,20 @@ +package com.hackathon.alddeul_babsang.data.datasourceimpl + +import com.hackathon.alddeul_babsang.data.datasource.ReportDataSource +import com.hackathon.alddeul_babsang.data.dto.BaseResponse +import com.hackathon.alddeul_babsang.data.dto.request.RequestReportDto +import com.hackathon.alddeul_babsang.data.dto.request.RequestReportWriteDto +import com.hackathon.alddeul_babsang.data.dto.response.ResponseReportDto +import com.hackathon.alddeul_babsang.data.service.ReportApiService +import javax.inject.Inject + +class ReportDataSourceImpl @Inject constructor( + private val reportApiService: ReportApiService +) : ReportDataSource { + override suspend fun postReports(userId : Int): BaseResponse> { + return reportApiService.postReports(userId) + } + + override suspend fun postReportWrite(requestReportWriteDto: RequestReportWriteDto): BaseResponse { + return reportApiService.postReportWrite(requestReportWriteDto) +}} \ No newline at end of file diff --git a/app/src/main/java/com/hackathon/alddeul_babsang/data/dto/request/RequestReportDto.kt b/app/src/main/java/com/hackathon/alddeul_babsang/data/dto/request/RequestReportDto.kt new file mode 100644 index 0000000..02aabb0 --- /dev/null +++ b/app/src/main/java/com/hackathon/alddeul_babsang/data/dto/request/RequestReportDto.kt @@ -0,0 +1,7 @@ +package com.hackathon.alddeul_babsang.data.dto.request + +import kotlinx.serialization.SerialName + +class RequestReportDto ( + @SerialName("userId") val userId: Long +) \ No newline at end of file diff --git a/app/src/main/java/com/hackathon/alddeul_babsang/data/dto/request/RequestReportWriteDto.kt b/app/src/main/java/com/hackathon/alddeul_babsang/data/dto/request/RequestReportWriteDto.kt new file mode 100644 index 0000000..ebd076c --- /dev/null +++ b/app/src/main/java/com/hackathon/alddeul_babsang/data/dto/request/RequestReportWriteDto.kt @@ -0,0 +1,16 @@ +package com.hackathon.alddeul_babsang.data.dto.request + +import kotlinx.serialization.Serializable + +@Serializable +data class RequestReportWriteDto ( + val name : String, + val category: String, + val address: String, + val contact: String, + val menuName1: String, + val menuPrice1: Int, + val menuName2: String, + val menuPrice2: Int, + val imageUrl: String? = null +) \ No newline at end of file diff --git a/app/src/main/java/com/hackathon/alddeul_babsang/data/dto/response/ResponseGetReviewDto.kt b/app/src/main/java/com/hackathon/alddeul_babsang/data/dto/response/ResponseGetReviewDto.kt index 6343a11..8cdfb44 100644 --- a/app/src/main/java/com/hackathon/alddeul_babsang/data/dto/response/ResponseGetReviewDto.kt +++ b/app/src/main/java/com/hackathon/alddeul_babsang/data/dto/response/ResponseGetReviewDto.kt @@ -14,4 +14,6 @@ data class Review ( @SerialName("nickname") val nickname: String, @SerialName("rate") val rate: Double, @SerialName("content") val content: String, + @SerialName("image") val imageUrl: String, + @SerialName("date") val date: String ) \ No newline at end of file diff --git a/app/src/main/java/com/hackathon/alddeul_babsang/data/dto/response/ResponseReportDto.kt b/app/src/main/java/com/hackathon/alddeul_babsang/data/dto/response/ResponseReportDto.kt new file mode 100644 index 0000000..c455b69 --- /dev/null +++ b/app/src/main/java/com/hackathon/alddeul_babsang/data/dto/response/ResponseReportDto.kt @@ -0,0 +1,16 @@ +package com.hackathon.alddeul_babsang.data.dto.response + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class ResponseReportDto( + @SerialName("storeId") val id: Long, + @SerialName("name") val name: String, + @SerialName("category") val category: String, + @SerialName("address") val address: String, + @SerialName("contact") val contact: String, + @SerialName("imageUrl") val imageUrl: String? = null, + @SerialName("favorite") val favorite: Boolean +) + diff --git a/app/src/main/java/com/hackathon/alddeul_babsang/data/repositoryimpl/ReportRepositoryImpl.kt b/app/src/main/java/com/hackathon/alddeul_babsang/data/repositoryimpl/ReportRepositoryImpl.kt new file mode 100644 index 0000000..c3f84b9 --- /dev/null +++ b/app/src/main/java/com/hackathon/alddeul_babsang/data/repositoryimpl/ReportRepositoryImpl.kt @@ -0,0 +1,48 @@ +package com.hackathon.alddeul_babsang.data.repositoryimpl + +import com.hackathon.alddeul_babsang.data.datasource.ReportDataSource +import com.hackathon.alddeul_babsang.data.dto.request.RequestReportWriteDto +import com.hackathon.alddeul_babsang.data.dto.response.ResponseReportDto +import com.hackathon.alddeul_babsang.domain.repository.ReportRepository +import javax.inject.Inject + +class ReportRepositoryImpl @Inject constructor( + private val reportDataSource: ReportDataSource +) : ReportRepository { + override suspend fun postReports( + userId: Int + ): Result> { + return runCatching { + reportDataSource.postReports( + userId = userId + ).result ?: emptyList() + } + } + + override suspend fun postReportWrite( + name: String, + category: String, + address: String, + contact: String, + menuName1: String, + menuPrice1: Int, + menuName2: String, + menuPrice2: Int, + imageUrl: String + ): Result { + return runCatching { + reportDataSource.postReportWrite( + requestReportWriteDto = RequestReportWriteDto( + name = name, + category = category, + address = address, + contact = contact, + menuName1 = menuName1, + menuPrice1 = menuPrice1, + menuName2 = menuName2, + menuPrice2 = menuPrice2 + ) + ).result ?: "" + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/hackathon/alddeul_babsang/data/service/ReportApiService.kt b/app/src/main/java/com/hackathon/alddeul_babsang/data/service/ReportApiService.kt new file mode 100644 index 0000000..f5c7550 --- /dev/null +++ b/app/src/main/java/com/hackathon/alddeul_babsang/data/service/ReportApiService.kt @@ -0,0 +1,24 @@ +package com.hackathon.alddeul_babsang.data.service + +import com.hackathon.alddeul_babsang.data.dto.BaseResponse +import com.hackathon.alddeul_babsang.data.dto.request.RequestReportDto +import com.hackathon.alddeul_babsang.data.dto.request.RequestReportWriteDto +import com.hackathon.alddeul_babsang.data.dto.response.ResponseReportDto +import com.sopt.data.service.ApiKeyStorage.POST +import com.sopt.data.service.ApiKeyStorage.REPORTS +import retrofit2.http.Body +import retrofit2.http.POST +import retrofit2.http.Query + +interface ReportApiService { + @POST("/$REPORTS/") + suspend fun postReports( + @Query("userId") userId: Int + ): BaseResponse> + + @POST("/$REPORTS/$POST") + suspend fun postReportWrite( + @Body requestReportWriteDto: RequestReportWriteDto + ): BaseResponse + +} \ No newline at end of file diff --git a/app/src/main/java/com/hackathon/alddeul_babsang/domain/entity/BabsangEntity.kt b/app/src/main/java/com/hackathon/alddeul_babsang/domain/entity/BabsangEntity.kt new file mode 100644 index 0000000..da0c4b1 --- /dev/null +++ b/app/src/main/java/com/hackathon/alddeul_babsang/domain/entity/BabsangEntity.kt @@ -0,0 +1,11 @@ +package com.hackathon.alddeul_babsang.domain.entity + +data class BabsangEntity( + val id: Long, + val avatar: String? = null, + val name: String, + val codeName: String, + val address: String, + val phone: String, + val favorite: Boolean = false, +) \ No newline at end of file diff --git a/app/src/main/java/com/hackathon/alddeul_babsang/domain/entity/ReportEntity.kt b/app/src/main/java/com/hackathon/alddeul_babsang/domain/entity/ReportEntity.kt new file mode 100644 index 0000000..40d8097 --- /dev/null +++ b/app/src/main/java/com/hackathon/alddeul_babsang/domain/entity/ReportEntity.kt @@ -0,0 +1,11 @@ +package com.hackathon.alddeul_babsang.domain.entity + +data class ReportEntity( + val id: Long, + val avatar: String? = null, + val name: String, + val codeName: String, + val address: String, + val phone: String, + val favorite: Boolean = false, +) \ No newline at end of file diff --git a/app/src/main/java/com/hackathon/alddeul_babsang/domain/repository/ReportRepository.kt b/app/src/main/java/com/hackathon/alddeul_babsang/domain/repository/ReportRepository.kt new file mode 100644 index 0000000..54f3578 --- /dev/null +++ b/app/src/main/java/com/hackathon/alddeul_babsang/domain/repository/ReportRepository.kt @@ -0,0 +1,23 @@ +package com.hackathon.alddeul_babsang.domain.repository + +import com.hackathon.alddeul_babsang.data.dto.response.ResponseReportDto + +interface ReportRepository { + suspend fun postReports( + userId: Int + ): Result> + + suspend fun postReportWrite( + name: String, + category: String, + address: String, + contact: String, + menuName1: String, + menuPrice1: Int, + menuName2: String, + menuPrice2: Int, + imageUrl: String, + ): Result + +} + diff --git a/app/src/main/java/com/hackathon/alddeul_babsang/presentation/babsang/screen/BabsangItem.kt b/app/src/main/java/com/hackathon/alddeul_babsang/presentation/babsang/screen/BabsangItem.kt index bac5a52..2cea722 100644 --- a/app/src/main/java/com/hackathon/alddeul_babsang/presentation/babsang/screen/BabsangItem.kt +++ b/app/src/main/java/com/hackathon/alddeul_babsang/presentation/babsang/screen/BabsangItem.kt @@ -25,11 +25,9 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import coil.compose.AsyncImage import com.hackathon.alddeul_babsang.R -import com.hackathon.alddeul_babsang.core_ui.theme.AlddeulBabsangTheme import com.hackathon.alddeul_babsang.core_ui.theme.Gray300 import com.hackathon.alddeul_babsang.core_ui.theme.Orange700 import com.hackathon.alddeul_babsang.core_ui.theme.Orange800 @@ -38,8 +36,6 @@ import com.hackathon.alddeul_babsang.core_ui.theme.body2Regular import com.hackathon.alddeul_babsang.core_ui.theme.body4Regular import com.hackathon.alddeul_babsang.core_ui.theme.head4Bold import com.hackathon.alddeul_babsang.data.dto.response.ResponseBabsangDto -import com.hackathon.alddeul_babsang.domain.entity.LikesEntity -import com.hackathon.alddeul_babsang.presentation.profile.screen.LikeItem @Composable fun BabsangItem( diff --git a/app/src/main/java/com/hackathon/alddeul_babsang/presentation/babsang/screen/BabsangViewModel.kt b/app/src/main/java/com/hackathon/alddeul_babsang/presentation/babsang/screen/BabsangViewModel.kt index 89b4f40..b5f053e 100644 --- a/app/src/main/java/com/hackathon/alddeul_babsang/presentation/babsang/screen/BabsangViewModel.kt +++ b/app/src/main/java/com/hackathon/alddeul_babsang/presentation/babsang/screen/BabsangViewModel.kt @@ -4,7 +4,6 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.hackathon.alddeul_babsang.data.dto.response.ResponseBabsangDto import com.hackathon.alddeul_babsang.domain.entity.BabsangRecommendEntity -import com.hackathon.alddeul_babsang.domain.entity.LikesEntity import com.hackathon.alddeul_babsang.domain.repository.BabsangRepository import com.hackathon.alddeul_babsang.util.UiState import dagger.hilt.android.lifecycle.HiltViewModel @@ -70,51 +69,4 @@ class BabsangViewModel @Inject constructor( address = "용산구", ) ) - val mockBabsang = listOf( - LikesEntity( - id = 1, - avatar = null, - name = "송이네 밥상", - codeName = "기타외식업", - address = "서울특별시 용산구 청파동 81", - phone = "02-210-0120", - favorite = true - ), - LikesEntity( - id = 2, - avatar = null, - name = "송이네 일식", - codeName = "경양식/일식", - address = "서울특별시 용산구 청파동 11", - phone = "02-210-0220", - favorite = true - ), - LikesEntity( - id = 3, - avatar = null, - name = "송이네 한식", - codeName = "한식", - address = "서울특별시 용산구 청파동 31", - phone = "02-223-0220", - favorite = true - ), - LikesEntity( - id = 4, - avatar = null, - name = "송이네 중식", - codeName = "중식", - address = "서울특별시 용산구 청파동 31", - phone = "02-223-0220", - favorite = true - ), - LikesEntity( - id = 4, - avatar = "https://avatars.githubusercontent.com/u/166610834?s=400&u=568eacc2e4696d563a4fd732c148edba2196e4f6&v=4", - name = "송이네 밥상", - codeName = "중식", - address = "서울특별시 용산구 청파동 31", - phone = "02-223-0220", - favorite = true - ) - ) } \ No newline at end of file diff --git a/app/src/main/java/com/hackathon/alddeul_babsang/presentation/detail/screen/ReviewItem.kt b/app/src/main/java/com/hackathon/alddeul_babsang/presentation/detail/screen/ReviewItem.kt index e78b105..044b0b0 100644 --- a/app/src/main/java/com/hackathon/alddeul_babsang/presentation/detail/screen/ReviewItem.kt +++ b/app/src/main/java/com/hackathon/alddeul_babsang/presentation/detail/screen/ReviewItem.kt @@ -50,7 +50,7 @@ fun ReviewItem( verticalAlignment = Alignment.CenterVertically ) { AsyncImage( - model = "", + model = data.imageUrl, contentDescription = null, placeholder = painterResource(id = R.drawable.ic_launcher_background), modifier = Modifier diff --git a/app/src/main/java/com/hackathon/alddeul_babsang/presentation/profile/screen/LikeItem.kt b/app/src/main/java/com/hackathon/alddeul_babsang/presentation/profile/screen/LikeItem.kt index 3057997..9e2e712 100644 --- a/app/src/main/java/com/hackathon/alddeul_babsang/presentation/profile/screen/LikeItem.kt +++ b/app/src/main/java/com/hackathon/alddeul_babsang/presentation/profile/screen/LikeItem.kt @@ -25,11 +25,9 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import coil.compose.AsyncImage import com.hackathon.alddeul_babsang.R -import com.hackathon.alddeul_babsang.core_ui.theme.AlddeulBabsangTheme import com.hackathon.alddeul_babsang.core_ui.theme.Gray300 import com.hackathon.alddeul_babsang.core_ui.theme.Orange700 import com.hackathon.alddeul_babsang.core_ui.theme.Orange800 @@ -38,12 +36,12 @@ import com.hackathon.alddeul_babsang.core_ui.theme.body2Regular import com.hackathon.alddeul_babsang.core_ui.theme.body4Regular import com.hackathon.alddeul_babsang.core_ui.theme.head4Bold import com.hackathon.alddeul_babsang.data.dto.response.FavoriteRestaurantDto -import com.hackathon.alddeul_babsang.domain.entity.LikesEntity @Composable fun LikeItem( onClick: () -> Unit = {}, - data: FavoriteRestaurantDto + data: FavoriteRestaurantDto, + likeViewModel: LikeViewModel ) { var isFavorite by remember { mutableStateOf(data.favorite) } @@ -81,6 +79,7 @@ fun LikeItem( .clickable { // 클릭 시 좋아요 상태를 토글 isFavorite = !isFavorite + likeViewModel.postLike(storeId = data.restaurantId) } ) } diff --git a/app/src/main/java/com/hackathon/alddeul_babsang/presentation/profile/screen/LikeScreen.kt b/app/src/main/java/com/hackathon/alddeul_babsang/presentation/profile/screen/LikeScreen.kt index fc1f23c..a27908b 100644 --- a/app/src/main/java/com/hackathon/alddeul_babsang/presentation/profile/screen/LikeScreen.kt +++ b/app/src/main/java/com/hackathon/alddeul_babsang/presentation/profile/screen/LikeScreen.kt @@ -39,6 +39,7 @@ import com.hackathon.alddeul_babsang.core_ui.theme.head4Bold import com.hackathon.alddeul_babsang.core_ui.theme.head6Semi import com.hackathon.alddeul_babsang.presentation.profile.navigation.ProfileNavigator import com.hackathon.alddeul_babsang.util.UiState +import timber.log.Timber @Composable fun LikeRoute( @@ -48,12 +49,24 @@ fun LikeRoute( val systemUiController = rememberSystemUiController() val likeViewModel: LikeViewModel = hiltViewModel() + val postLikeState by likeViewModel.postLikeState.collectAsStateWithLifecycle(UiState.Empty) + SideEffect { systemUiController.setStatusBarColor( color = White ) } + when(postLikeState) { + is UiState.Success -> { + navigator.navigateBack() + } + is UiState.Failure -> { + Timber.e((postLikeState as UiState.Failure).msg) + } + else -> {} + } + LaunchedEffect(Unit) { likeViewModel.getLikes() } @@ -127,7 +140,8 @@ fun LikeScreen( items((getLikesState as UiState.Success).data) { item -> LikeItem( onClick = { onItemClick(item.restaurantId) }, - data = item + data = item, + likeViewModel = likeViewModel ) } } diff --git a/app/src/main/java/com/hackathon/alddeul_babsang/presentation/profile/screen/LikeViewModel.kt b/app/src/main/java/com/hackathon/alddeul_babsang/presentation/profile/screen/LikeViewModel.kt index 528cd0c..8697094 100644 --- a/app/src/main/java/com/hackathon/alddeul_babsang/presentation/profile/screen/LikeViewModel.kt +++ b/app/src/main/java/com/hackathon/alddeul_babsang/presentation/profile/screen/LikeViewModel.kt @@ -21,6 +21,10 @@ class LikeViewModel @Inject constructor( MutableStateFlow>>(UiState.Empty) val getLikesState: StateFlow>> = _getLikesState + private val _postLikeState = + MutableStateFlow>(UiState.Empty) + val postLikeState: StateFlow> = _postLikeState + fun getLikes() = viewModelScope.launch { _getLikesState.emit(UiState.Loading) profileRepository.getLikes(userId = 1).fold( @@ -33,6 +37,25 @@ class LikeViewModel @Inject constructor( ) } + fun postLike( + userId: Long = 1, + storeId: Long + ) = viewModelScope.launch { + _postLikeState.emit(UiState.Loading) + profileRepository.postLike( + userId, storeId + ).fold( + onSuccess = { + _postLikeState.emit(UiState.Success(it)) + }, + onFailure = { + _postLikeState.emit(UiState.Failure(it.message.toString())) + } + ) + } + + + val mockLikes = listOf( LikesEntity( id = 1, diff --git a/app/src/main/java/com/hackathon/alddeul_babsang/presentation/report/screen/ReportItem.kt b/app/src/main/java/com/hackathon/alddeul_babsang/presentation/report/screen/ReportItem.kt index 63dcce3..b44d243 100644 --- a/app/src/main/java/com/hackathon/alddeul_babsang/presentation/report/screen/ReportItem.kt +++ b/app/src/main/java/com/hackathon/alddeul_babsang/presentation/report/screen/ReportItem.kt @@ -37,12 +37,12 @@ import com.hackathon.alddeul_babsang.core_ui.theme.Orange900 import com.hackathon.alddeul_babsang.core_ui.theme.body2Regular import com.hackathon.alddeul_babsang.core_ui.theme.body4Regular import com.hackathon.alddeul_babsang.core_ui.theme.head4Bold -import com.hackathon.alddeul_babsang.domain.entity.LikesEntity +import com.hackathon.alddeul_babsang.data.dto.response.ResponseReportDto @Composable fun ReportItem( onClick: () -> Unit = {}, - data: LikesEntity + data: ResponseReportDto ) { var isFavorite by remember { mutableStateOf(data.favorite) } @@ -71,7 +71,7 @@ fun ReportItem( .clip(RoundedCornerShape(topStart = 14.dp, topEnd = 14.dp)) ) { // AsyncImage 로드 - LoadImageWithPlaceholder(data.codeName, data.avatar) + LoadImageWithPlaceholder(data.category, data.imageUrl) Image( painter = painterResource(heartIconId), @@ -95,7 +95,7 @@ fun ReportItem( ) Spacer(modifier = Modifier.width(15.dp)) Text( - text = data.codeName, + text = data.category, style = body2Regular, color = Orange800, modifier = Modifier @@ -112,7 +112,7 @@ fun ReportItem( ) Spacer(modifier = Modifier.height(7.dp)) Text( - text = data.phone, + text = data.contact, style = body4Regular, color = Gray300, modifier = Modifier.padding(start = 20.dp) @@ -167,13 +167,13 @@ fun LoadImageWithPlaceholder(codeName: String, imageUrl: String?) { fun BabsangItemPreview() { AlddeulBabsangTheme { ReportItem( - data = LikesEntity( + data = ResponseReportDto( id = 1, - avatar = null, + imageUrl = null, name = "송이네 밥상", - codeName = "경양식/일식", + category = "경양식/일식", address = "서울특별시 용산구 청파동 11", - phone = "02-210-0220", + contact = "02-210-0220", favorite = true ) ) diff --git a/app/src/main/java/com/hackathon/alddeul_babsang/presentation/report/screen/ReportScreen.kt b/app/src/main/java/com/hackathon/alddeul_babsang/presentation/report/screen/ReportScreen.kt index aeda380..144aa86 100644 --- a/app/src/main/java/com/hackathon/alddeul_babsang/presentation/report/screen/ReportScreen.kt +++ b/app/src/main/java/com/hackathon/alddeul_babsang/presentation/report/screen/ReportScreen.kt @@ -3,42 +3,54 @@ package com.hackathon.alddeul_babsang.presentation.report.screen import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.SideEffect +import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel +import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.google.accompanist.systemuicontroller.rememberSystemUiController import com.hackathon.alddeul_babsang.R +import com.hackathon.alddeul_babsang.core_ui.component.LoadingCircleIndicator import com.hackathon.alddeul_babsang.core_ui.theme.AlddeulBabsangTheme import com.hackathon.alddeul_babsang.core_ui.theme.Blue import com.hackathon.alddeul_babsang.core_ui.theme.Gray900 import com.hackathon.alddeul_babsang.core_ui.theme.Orange900 import com.hackathon.alddeul_babsang.core_ui.theme.White import com.hackathon.alddeul_babsang.core_ui.theme.head6Bold +import com.hackathon.alddeul_babsang.core_ui.theme.head6Semi import com.hackathon.alddeul_babsang.core_ui.theme.head7Bold import com.hackathon.alddeul_babsang.core_ui.theme.title4Bold import com.hackathon.alddeul_babsang.presentation.report.navigation.ReportNavigator +import com.hackathon.alddeul_babsang.util.UiState @Composable fun ReportRoute( navigator: ReportNavigator ) { - val babsangListViewModel: ReportViewModel = hiltViewModel() + val reportViewModel: ReportViewModel = hiltViewModel() val systemUiController = rememberSystemUiController() + LaunchedEffect(Unit) { + reportViewModel.postReports() + } + SideEffect { systemUiController.setStatusBarColor( color = White @@ -51,7 +63,7 @@ fun ReportRoute( navigator.navigateReportWrite() }, - babsangListViewModel = babsangListViewModel + reportViewModel = reportViewModel ) } @@ -60,8 +72,11 @@ fun ReportRoute( fun ReportScreen( onItemClick: (Long) -> Unit = {}, onReportWriteClick: () -> Unit = {}, - babsangListViewModel: ReportViewModel + reportViewModel: ReportViewModel ) { + + val getReportState by reportViewModel.getReportState.collectAsStateWithLifecycle(UiState.Empty) + Scaffold( floatingActionButton = { Button( @@ -108,12 +123,51 @@ fun ReportScreen( style = head7Bold, color = Gray900 ) } - items(babsangListViewModel.mockReportBabsang) { item -> - ReportItem( - onClick = { onItemClick(item.id) }, - data = item - ) + + when (getReportState) { + is UiState.Loading -> { + item { + LoadingCircleIndicator() + } } + + is UiState.Success -> { + val data = (getReportState as UiState.Success).data + if (data.isEmpty()) { + item { + Text( + text = "밥상 데이터가 없어요", + style = head6Semi, + color = Orange900, + modifier = Modifier.padding(vertical = 20.dp) + ) + } + } else { + itemsIndexed(data) { index, item -> + ReportItem( + onClick = { onItemClick(item.id) }, + data = item + ) + if (index != data.size - 1) { + Spacer(modifier = Modifier.height(16.dp)) + } + } + } + } + + is UiState.Failure -> { + item { + Text( + text = (getReportState as UiState.Failure).msg, + style = head6Semi, + color = Orange900, + modifier = Modifier.padding(vertical = 20.dp) + ) + } + } + + else -> {} + } } } } @@ -122,12 +176,11 @@ fun ReportScreen( @Preview @Composable fun ReportScreenPreview() { - val babsangListViewModel: ReportViewModel = hiltViewModel() AlddeulBabsangTheme { ReportScreen( onReportWriteClick = { }, - babsangListViewModel = babsangListViewModel + reportViewModel = hiltViewModel() ) } diff --git a/app/src/main/java/com/hackathon/alddeul_babsang/presentation/report/screen/ReportViewModel.kt b/app/src/main/java/com/hackathon/alddeul_babsang/presentation/report/screen/ReportViewModel.kt index 0f62a1b..d3d2a9c 100644 --- a/app/src/main/java/com/hackathon/alddeul_babsang/presentation/report/screen/ReportViewModel.kt +++ b/app/src/main/java/com/hackathon/alddeul_babsang/presentation/report/screen/ReportViewModel.kt @@ -1,14 +1,73 @@ package com.hackathon.alddeul_babsang.presentation.report.screen import androidx.lifecycle.ViewModel -import com.hackathon.alddeul_babsang.domain.entity.LikesEntity +import androidx.lifecycle.viewModelScope +import com.hackathon.alddeul_babsang.data.dto.response.ResponseReportDto +import com.hackathon.alddeul_babsang.domain.entity.ReportEntity +import com.hackathon.alddeul_babsang.domain.repository.ReportRepository +import com.hackathon.alddeul_babsang.util.UiState import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.launch import javax.inject.Inject + @HiltViewModel -class ReportViewModel @Inject constructor() : ViewModel() { +class ReportViewModel @Inject constructor( + private val reportRepository: ReportRepository +) : ViewModel() { + private val _getReportState = + MutableStateFlow>>(UiState.Empty) + val getReportState: StateFlow>> = _getReportState + + private val _postReportWriteState = + MutableStateFlow>(UiState.Empty) + val postReportWriteState: StateFlow> = _postReportWriteState + + + fun postReports( + userId : Long = 1 + ) = viewModelScope.launch { + _getReportState.emit(UiState.Loading) + reportRepository.postReports(userId).fold( + onSuccess = { + _getReportState.emit(UiState.Success(it)) + }, + onFailure = { + _getReportState.emit(UiState.Failure(it.message.toString())) + } + ) + } + + fun postReportWrite( + name: String, + category: String, + address: String, + contact: String, + menuName1: String, + menuPrice1: Int, + menuName2: String, + menuPrice2: Int, + imageUrl: String + ) = viewModelScope.launch { + _postReportWriteState.emit(UiState.Loading) + reportRepository.postReportWrite( + name, category, address, contact, menuName1, menuPrice1, menuName2, menuPrice2, imageUrl + ).fold( + onSuccess = { + _postReportWriteState.emit(UiState.Success(it)) + }, + onFailure = { + _postReportWriteState.emit(UiState.Failure(it.message.toString())) + } + ) + } + + + val mockReportBabsang = listOf( - LikesEntity( + ReportEntity( id = 1, avatar = null, name = "송이네 밥상", @@ -17,7 +76,7 @@ class ReportViewModel @Inject constructor() : ViewModel() { phone = "02-210-0120", favorite = true ), - LikesEntity( + ReportEntity( id = 2, avatar = null, name = "송이네 일식", @@ -26,7 +85,7 @@ class ReportViewModel @Inject constructor() : ViewModel() { phone = "02-210-0220", favorite = true ), - LikesEntity( + ReportEntity( id = 3, avatar = null, name = "송이네 한식", @@ -35,7 +94,7 @@ class ReportViewModel @Inject constructor() : ViewModel() { phone = "02-223-0220", favorite = true ), - LikesEntity( + ReportEntity( id = 4, avatar = null, name = "송이네 중식", @@ -44,7 +103,7 @@ class ReportViewModel @Inject constructor() : ViewModel() { phone = "02-223-0220", favorite = true ), - LikesEntity( + ReportEntity( id = 4, avatar = "https://avatars.githubusercontent.com/u/166610834?s=400&u=568eacc2e4696d563a4fd732c148edba2196e4f6&v=4", name = "송이네 밥상", diff --git a/app/src/main/java/com/hackathon/alddeul_babsang/presentation/report/screen/ReportWriteScreen.kt b/app/src/main/java/com/hackathon/alddeul_babsang/presentation/report/screen/ReportWriteScreen.kt index c78e54a..bb016c8 100644 --- a/app/src/main/java/com/hackathon/alddeul_babsang/presentation/report/screen/ReportWriteScreen.kt +++ b/app/src/main/java/com/hackathon/alddeul_babsang/presentation/report/screen/ReportWriteScreen.kt @@ -43,14 +43,14 @@ import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import androidx.hilt.navigation.compose.hiltViewModel +import androidx.lifecycle.compose.collectAsStateWithLifecycle import coil.compose.rememberAsyncImagePainter import com.hackathon.alddeul_babsang.R import com.hackathon.alddeul_babsang.core_ui.component.AlddeulButton import com.hackathon.alddeul_babsang.core_ui.component.AlddeulHeader import com.hackathon.alddeul_babsang.core_ui.component.ReportWriteArea -import com.hackathon.alddeul_babsang.core_ui.theme.AlddeulBabsangTheme import com.hackathon.alddeul_babsang.core_ui.theme.Gray100 import com.hackathon.alddeul_babsang.core_ui.theme.Gray600 import com.hackathon.alddeul_babsang.core_ui.theme.Gray900 @@ -59,15 +59,31 @@ import com.hackathon.alddeul_babsang.core_ui.theme.White import com.hackathon.alddeul_babsang.core_ui.theme.body2Semi import com.hackathon.alddeul_babsang.core_ui.theme.head4Bold import com.hackathon.alddeul_babsang.presentation.report.navigation.ReportNavigator +import com.hackathon.alddeul_babsang.util.UiState import com.hackathon.alddeul_babsang.util.toast +import timber.log.Timber @Composable fun ReportWriteRoute( navigator: ReportNavigator ) { + val reportViewModel: ReportViewModel = hiltViewModel() + val postReportWriteState by reportViewModel.postReportWriteState.collectAsStateWithLifecycle( + UiState.Empty + ) + + when(postReportWriteState) { + is UiState.Success -> { + navigator.navigateBack() + } + is UiState.Failure -> { + Timber.e((postReportWriteState as UiState.Failure).msg) + } + else -> {} + } ReportWriteScreen( onBackClick = { navigator.navigateBack() }, - onButtonClick = { navigator.navigateBack() } + reportViewModel = reportViewModel ) } @@ -75,7 +91,7 @@ fun ReportWriteRoute( @Composable fun ReportWriteScreen( onBackClick: () -> Unit = {}, - onButtonClick: () -> Unit = {} + reportViewModel: ReportViewModel ) { var imageUri by remember { mutableStateOf(null) } val galleryLauncher = rememberLauncherForActivityResult( @@ -226,19 +242,26 @@ fun ReportWriteScreen( Spacer(modifier = Modifier.height(110.dp)) AlddeulButton(text = R.string.btn_report_complete) { if (name.isNotEmpty() && address.isNotEmpty() && phone.isNotEmpty() && menu1.isNotEmpty() && menu1price.isNotEmpty()) { - onButtonClick() + reportViewModel.postReportWrite( + name = name, + category = when(selectedCategory){ + 0 -> "KOREAN" + 1 -> "CHINESE" + 2 -> "WESTERN_JAPANESE" + else -> "OTHER" + }, + address = address, + contact = phone, + menuName1 = menu1, + menuPrice1 = menu1price.toInt(), + menuName2 = menu2, + menuPrice2 = menu2price.toInt(), + imageUrl = "" + ) } else { context.toast(context.getString(R.string.toast_report_failure)) } } } } -} - -@Preview(showBackground = true) -@Composable -fun ReportWriteScreenPreview() { - AlddeulBabsangTheme { - ReportWriteScreen() - } } \ No newline at end of file