Skip to content

Commit

Permalink
Merge pull request #33 from DACOS-SOLUX-Hackathon-Team5/feautre/#32-r…
Browse files Browse the repository at this point in the history
…eview-api

[Feautre/#32] : 리뷰 api 연결
  • Loading branch information
seoyeonsw authored Nov 8, 2024
2 parents 76384e2 + 9d0f221 commit 7451670
Show file tree
Hide file tree
Showing 20 changed files with 274 additions and 141 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,8 @@ object RetrofitModule {
@Singleton
fun provideOkHttpClient(
loggingInterceptor: HttpLoggingInterceptor,
@AccessToken tokenInterceptor: Interceptor,
): OkHttpClient = OkHttpClient.Builder()
.addInterceptor(loggingInterceptor)
.addInterceptor(tokenInterceptor)
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.hackathon.alddeul_babsang.data.datasource

import com.hackathon.alddeul_babsang.data.dto.BaseResponse
import com.hackathon.alddeul_babsang.data.dto.response.ResponseGetReviewDto
import com.hackathon.alddeul_babsang.data.dto.response.ResponseReviewDto
import okhttp3.MultipartBody
import okhttp3.RequestBody
Expand All @@ -11,4 +12,8 @@ interface DetailDataSource {
data: Map<String, RequestBody>, // JSON 데이터를 포함하는 Map
reviewImage: MultipartBody.Part? = null // 이미지 파일
): BaseResponse<ResponseReviewDto>

suspend fun getReviews(
id: Long
): BaseResponse<ResponseGetReviewDto>
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package com.hackathon.alddeul_babsang.data.datasource

import com.hackathon.alddeul_babsang.data.dto.BaseResponse
import com.hackathon.alddeul_babsang.data.dto.request.RequestMapStoreDetailDto
import com.hackathon.alddeul_babsang.data.dto.response.ResponseMapStoreDetailDto
import com.hackathon.alddeul_babsang.data.dto.response.ResponseMapStoresDto

interface MapDataSource {
suspend fun getMapStores(): BaseResponse<List<ResponseMapStoresDto>>
suspend fun getMapStoreDetail(id: Long): BaseResponse<ResponseMapStoreDetailDto>
suspend fun postMapStoreDetail(
id: Long,
requestMapStoreDetailDto: RequestMapStoreDetailDto
): BaseResponse<ResponseMapStoreDetailDto>
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.hackathon.alddeul_babsang.data.datasourceimpl

import com.hackathon.alddeul_babsang.data.datasource.DetailDataSource
import com.hackathon.alddeul_babsang.data.dto.BaseResponse
import com.hackathon.alddeul_babsang.data.dto.response.ResponseGetReviewDto
import com.hackathon.alddeul_babsang.data.dto.response.ResponseReviewDto
import com.hackathon.alddeul_babsang.data.service.DetailApiService
import okhttp3.MultipartBody
Expand All @@ -19,4 +20,8 @@ class DetailDataSourceImpl @Inject constructor(
return detailApiService.postReview(storeId, data, reviewImage)
}

override suspend fun getReviews(id: Long): BaseResponse<ResponseGetReviewDto> {
return detailApiService.getReviews(id)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.hackathon.alddeul_babsang.data.datasourceimpl

import com.hackathon.alddeul_babsang.data.datasource.MapDataSource
import com.hackathon.alddeul_babsang.data.dto.BaseResponse
import com.hackathon.alddeul_babsang.data.dto.request.RequestMapStoreDetailDto
import com.hackathon.alddeul_babsang.data.dto.response.ResponseMapStoreDetailDto
import com.hackathon.alddeul_babsang.data.dto.response.ResponseMapStoresDto
import com.hackathon.alddeul_babsang.data.service.MapApiService
Expand All @@ -14,7 +15,10 @@ class MapDataSourceImpl @Inject constructor(
return mapApiService.getMapStores()
}

override suspend fun getMapStoreDetail(id: Long): BaseResponse<ResponseMapStoreDetailDto> {
return mapApiService.getMapStoreDetail(id)
override suspend fun postMapStoreDetail(
id: Long,
requestMapStoreDetailDto: RequestMapStoreDetailDto
): BaseResponse<ResponseMapStoreDetailDto> {
return mapApiService.postMapStoreDetail(id, requestMapStoreDetailDto)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.hackathon.alddeul_babsang.data.dto.request

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class RequestMapStoreDetailDto (
@SerialName("userId") val userId: Long,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.hackathon.alddeul_babsang.data.dto.response

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class ResponseGetReviewDto (
@SerialName("reviewCnt") val reviewCnt: Int,
@SerialName("reviewList") val reviewList: List<Review>
)

@Serializable
data class Review (
@SerialName("nickname") val nickname: String,
@SerialName("rate") val rate: Double,
@SerialName("content") val content: String,
)
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import kotlinx.serialization.Serializable

@Serializable
data class ResponseMapStoreDetailDto (
@SerialName("id") val id: Long,
@SerialName("storeId") val storeId: Long,
@SerialName("name") val name: String,
@SerialName("category") val category: String,
@SerialName("address") val address: String,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com.hackathon.alddeul_babsang.data.repositoryimpl

import com.hackathon.alddeul_babsang.data.datasource.DetailDataSource
import com.hackathon.alddeul_babsang.data.dto.response.Review
import com.hackathon.alddeul_babsang.domain.repository.DetailRepository
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.RequestBody.Companion.asRequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONObject
import java.io.File
import javax.inject.Inject

Expand Down Expand Up @@ -40,4 +40,10 @@ class DetailRepositoryImpl @Inject constructor(
).message
}
}

override suspend fun getReviews(id: Long): Result<List<Review>> {
return runCatching {
detailDataSource.getReviews(id).result?.reviewList ?: emptyList()
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.hackathon.alddeul_babsang.data.repositoryimpl

import com.hackathon.alddeul_babsang.data.datasource.MapDataSource
import com.hackathon.alddeul_babsang.data.dto.request.RequestMapStoreDetailDto
import com.hackathon.alddeul_babsang.data.dto.response.ResponseMapStoreDetailDto
import com.hackathon.alddeul_babsang.data.dto.response.ResponseMapStoresDto
import com.hackathon.alddeul_babsang.domain.repository.MapRepository
Expand All @@ -15,9 +16,17 @@ class MapRepositoryImpl @Inject constructor(
}
}

override suspend fun getMapStoreDetail(id: Long): Result<ResponseMapStoreDetailDto?> {
override suspend fun postMapStoreDetail(
id: Long,
userId: Long
): Result<ResponseMapStoreDetailDto?> {
return runCatching {
mapDataSource.getMapStoreDetail(id).result
mapDataSource.postMapStoreDetail(
id = id,
requestMapStoreDetailDto = RequestMapStoreDetailDto(
userId
)
).result
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ object ApiKeyStorage {
const val USER_ID = "userId"
const val STORE_ID = "storeId"
const val ID = "id"
const val REVIEWS = "reviews"
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
package com.hackathon.alddeul_babsang.data.service

import com.hackathon.alddeul_babsang.data.dto.BaseResponse
import com.hackathon.alddeul_babsang.data.dto.response.ResponseGetReviewDto
import com.hackathon.alddeul_babsang.data.dto.response.ResponseReviewDto
import com.sopt.data.service.ApiKeyStorage.ID
import com.sopt.data.service.ApiKeyStorage.REVIEW
import com.sopt.data.service.ApiKeyStorage.REVIEWS
import com.sopt.data.service.ApiKeyStorage.STORES
import com.sopt.data.service.ApiKeyStorage.STORE_ID
import okhttp3.MultipartBody
import okhttp3.RequestBody
import retrofit2.http.GET
import retrofit2.http.Multipart
import retrofit2.http.POST
import retrofit2.http.Part
Expand All @@ -20,4 +25,10 @@ interface DetailApiService {
@PartMap data: Map<String, @JvmSuppressWildcards RequestBody>,
@Part reviewImage: MultipartBody.Part? = null
): BaseResponse<ResponseReviewDto>

@GET("/$STORES/{$ID}/$REVIEWS")
suspend fun getReviews(
@Path("id") id: Long
): BaseResponse<ResponseGetReviewDto>

}
Original file line number Diff line number Diff line change
@@ -1,20 +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.RequestMapStoreDetailDto
import com.hackathon.alddeul_babsang.data.dto.response.ResponseMapStoreDetailDto
import com.hackathon.alddeul_babsang.data.dto.response.ResponseMapStoresDto
import com.sopt.data.service.ApiKeyStorage.ID
import com.sopt.data.service.ApiKeyStorage.MAP
import com.sopt.data.service.ApiKeyStorage.STORES
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.Path

interface MapApiService {
@GET("/$MAP/$STORES")
suspend fun getMapStores(): BaseResponse<List<ResponseMapStoresDto>>

@GET("/$MAP/$STORES/{$ID}")
suspend fun getMapStoreDetail(
@Path("id") id: Long
@POST("/$MAP/$STORES/{$ID}")
suspend fun postMapStoreDetail(
@Path("id") id: Long,
@Body requestMapStoreDetailDto: RequestMapStoreDetailDto
): BaseResponse<ResponseMapStoreDetailDto>
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.hackathon.alddeul_babsang.domain.repository

import com.hackathon.alddeul_babsang.data.dto.response.Review
import java.io.File

interface DetailRepository {
Expand All @@ -10,4 +11,8 @@ interface DetailRepository {
content: String,
reviewImage: File
): Result<String>

suspend fun getReviews(
id: Long
): Result<List<Review>>
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,8 @@ import com.hackathon.alddeul_babsang.data.dto.response.ResponseMapStoresDto

interface MapRepository {
suspend fun getMapStores(): Result<List<ResponseMapStoresDto>>
suspend fun getMapStoreDetail(id: Long): Result<ResponseMapStoreDetailDto?>
suspend fun postMapStoreDetail(
id: Long,
userId: Long
): Result<ResponseMapStoreDetailDto?>
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
Expand All @@ -42,13 +43,12 @@ import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
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.AsyncImage
import com.google.accompanist.systemuicontroller.rememberSystemUiController
import com.hackathon.alddeul_babsang.R
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.Gray200
import com.hackathon.alddeul_babsang.core_ui.theme.Gray300
Expand All @@ -63,6 +63,8 @@ import com.hackathon.alddeul_babsang.core_ui.theme.head7Regular
import com.hackathon.alddeul_babsang.core_ui.theme.head7Semi
import com.hackathon.alddeul_babsang.domain.entity.BabsangDetailEntity
import com.hackathon.alddeul_babsang.presentation.detail.navigation.DetailNavigator
import com.hackathon.alddeul_babsang.util.UiState
import timber.log.Timber
import kotlin.math.round

@Composable
Expand All @@ -79,6 +81,10 @@ fun DetailRoute(
)
}

LaunchedEffect(Unit) {
detailViewModel.getReviews(id)
}

DetailScreen(
data = detailViewModel.mockDetail,
onBackClick = { navigator.navigateBack() },
Expand All @@ -98,6 +104,7 @@ fun DetailScreen(
detailViewModel: DetailViewModel
) {
var isFavorite by remember { mutableStateOf(data.isFavorite) }
val getReviewsState by detailViewModel.getReviewsState.collectAsStateWithLifecycle(UiState.Empty)

Scaffold(
modifier = Modifier.fillMaxSize(),
Expand Down Expand Up @@ -278,13 +285,32 @@ fun DetailScreen(
color = Gray900
)
}
itemsIndexed(detailViewModel.mockReviews) { index, item ->
ReviewItem(
data = item
)
if (index != detailViewModel.mockReviews.size - 1) {
Spacer(modifier = Modifier.height(16.dp))
when (getReviewsState) {
is UiState.Success -> {
val data = (getReviewsState as UiState.Success).data
itemsIndexed(data) { index, item ->
ReviewItem(
data = item
)
if (index != data.size - 1) {
Spacer(modifier = Modifier.height(16.dp))
}
}
}

is UiState.Failure -> {
item {
Text(
text = (getReviewsState as UiState.Failure).msg,
style = head7Semi,
color = Orange700,
modifier = Modifier.padding(vertical = 20.dp)
)
}
Timber.e("Get reviews failed: ${(getReviewsState as UiState.Failure).msg}")
}

else -> {}
}
item {
Text(
Expand Down Expand Up @@ -314,15 +340,4 @@ fun DetailScreen(
}
}
}
}

@Preview(showBackground = true)
@Composable
fun DetailScreenPreview() {
AlddeulBabsangTheme {
DetailScreen(
data = DetailViewModel().mockDetail,
detailViewModel = hiltViewModel()
)
}
}
Loading

0 comments on commit 7451670

Please sign in to comment.