Skip to content

Commit

Permalink
#26 상세 페이지 비슷한 업소 추천 api
Browse files Browse the repository at this point in the history
  • Loading branch information
seoyeonsw committed Nov 8, 2024
1 parent c697ef9 commit c90b06f
Show file tree
Hide file tree
Showing 11 changed files with 191 additions and 48 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.hackathon.alddeul_babsang.data.datasource

import com.hackathon.alddeul_babsang.data.dto.BaseResponse
import com.hackathon.alddeul_babsang.data.dto.response.ResponseBabsangRecommendDto
import com.hackathon.alddeul_babsang.data.dto.response.ResponseDetailDto
import com.hackathon.alddeul_babsang.data.dto.response.ResponseDetailRecommendDto
import com.hackathon.alddeul_babsang.data.dto.response.ResponseGetReviewDto
import com.hackathon.alddeul_babsang.data.dto.response.ResponseReviewDto
import okhttp3.MultipartBody
Expand All @@ -22,4 +24,8 @@ interface DetailDataSource {
id: Int,
Userid: Int
): BaseResponse<ResponseDetailDto>

suspend fun postRecommendStores(
storeId: Int
): BaseResponse<List<ResponseDetailRecommendDto>>
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ 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.ResponseBabsangRecommendDto
import com.hackathon.alddeul_babsang.data.dto.response.ResponseDetailDto
import com.hackathon.alddeul_babsang.data.dto.response.ResponseDetailRecommendDto
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
Expand All @@ -29,4 +31,9 @@ class DetailDataSourceImpl @Inject constructor(
return detailApiService.postStoreDetail(id, Userid)
}

override suspend fun postRecommendStores(
storeId: Int
): BaseResponse<List<ResponseDetailRecommendDto>> {
return detailApiService.postRecommendStores(storeId)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.hackathon.alddeul_babsang.data.dto.request

import kotlinx.serialization.SerialName

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

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

@Serializable
data class ResponseDetailRecommendDto (
@SerialName("name") val name: String,
@SerialName("category") val category: String,
@SerialName("region") val region: String,
@SerialName("storeId") val storeId: Long,
)
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.hackathon.alddeul_babsang.data.repositoryimpl

import com.hackathon.alddeul_babsang.data.datasource.DetailDataSource
import com.hackathon.alddeul_babsang.data.dto.response.ResponseBabsangRecommendDto
import com.hackathon.alddeul_babsang.data.dto.response.ResponseDetailDto
import com.hackathon.alddeul_babsang.data.dto.response.ResponseDetailRecommendDto
import com.hackathon.alddeul_babsang.data.dto.response.Review
import com.hackathon.alddeul_babsang.domain.repository.DetailRepository
import okhttp3.MediaType.Companion.toMediaTypeOrNull
Expand Down Expand Up @@ -53,4 +55,14 @@ class DetailRepositoryImpl @Inject constructor(
detailDataSource.postStoreDetail(id = id, Userid = userId).result
}
}

override suspend fun postRecommendStores(
storeId: Int
): Result<List<ResponseDetailRecommendDto>> {
return runCatching {
detailDataSource.postRecommendStores(
storeId = storeId
).result ?: emptyList()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ object ApiKeyStorage {
const val ID = "id"
const val REVIEWS = "reviews"
const val RECOMMEND = "recommend"
const val SIMILAR = "similar"
}
Original file line number Diff line number Diff line change
@@ -1,12 +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.ResponseBabsangRecommendDto
import com.hackathon.alddeul_babsang.data.dto.response.ResponseDetailDto
import com.hackathon.alddeul_babsang.data.dto.response.ResponseDetailRecommendDto
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.RECOMMEND
import com.sopt.data.service.ApiKeyStorage.REVIEW
import com.sopt.data.service.ApiKeyStorage.REVIEWS
import com.sopt.data.service.ApiKeyStorage.SIMILAR
import com.sopt.data.service.ApiKeyStorage.STORES
import com.sopt.data.service.ApiKeyStorage.STORE_ID
import okhttp3.MultipartBody
Expand Down Expand Up @@ -39,4 +43,8 @@ interface DetailApiService {
@Query("Userid") Userid: Int
): BaseResponse<ResponseDetailDto>

@POST("/$RECOMMEND/$SIMILAR")
suspend fun postRecommendStores(
@Query("storeId") storeId: Int
) : BaseResponse<List<ResponseDetailRecommendDto>>
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.hackathon.alddeul_babsang.domain.repository

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

Expand All @@ -21,4 +23,8 @@ interface DetailRepository {
id: Int,
userId: Int
): Result<ResponseDetailDto?>

suspend fun postRecommendStores(
storeId: Int
): Result<List<ResponseDetailRecommendDto>>
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package com.hackathon.alddeul_babsang.presentation.detail.screen

import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
Expand All @@ -13,6 +16,7 @@ import androidx.compose.ui.Alignment
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
Expand All @@ -26,66 +30,82 @@ import com.hackathon.alddeul_babsang.core_ui.theme.Pink
import com.hackathon.alddeul_babsang.core_ui.theme.Yellow
import com.hackathon.alddeul_babsang.core_ui.theme.body1Semi
import com.hackathon.alddeul_babsang.core_ui.theme.body4Regular
import com.hackathon.alddeul_babsang.data.dto.response.ResponseDetailRecommendDto
import com.hackathon.alddeul_babsang.domain.entity.BabsangRecommendEntity
import com.hackathon.alddeul_babsang.presentation.babsang.screen.LoadImage

@Composable
fun DetailRecommendedItem(
data: BabsangRecommendEntity,
data: ResponseDetailRecommendDto,
onClick: () -> Unit = {}
) {
Column(
modifier = Modifier.clickable { onClick() }
) {
AsyncImage(
model = data.avatar ?: when (data.codeName) {
"한식" -> R.drawable.ic_korean_food
"중식" -> R.drawable.ic_chinese_food
"경양식/일식" -> R.drawable.ic_japanese_food
else -> R.drawable.ic_etc_food
},
contentDescription = null,
modifier = Modifier
.fillMaxWidth()
.clip(RoundedCornerShape(10.dp))
.height(200.dp)
.background(
color = when (data.codeName) {
"한식" -> Orange700
"중식" -> Yellow
"경양식/일식" -> Pink
"기타외식업" -> Blue
else -> Font_B04
},
shape = RoundedCornerShape(14.dp)
),
contentScale = if (data.avatar == null) ContentScale.None else ContentScale.FillBounds,
alignment = Alignment.Center
)
LoadImage2(data.category)

Text(
modifier = Modifier.padding(vertical = 5.dp),
text = data.name,
style = body1Semi,
color = Black
)
Text(
text = data.codeName,
text = data.category,
style = body4Regular,
color = Font_B04
)
}
}

@Composable
fun LoadImage2(codeName: String) {
val imageId = when (codeName) {
"WESTERN_JAPANESE" -> R.drawable.ic_japanese_food
"KOREAN" -> R.drawable.ic_korean_food
"CHINESE" -> R.drawable.ic_chinese_food
else -> R.drawable.ic_etc_food
}
val backgroundColor = when (codeName) {
"WESTERN_JAPANESE" -> Yellow
"KOREAN" -> Orange700
"CHINESE" -> Pink
else -> Blue
}

Box(
modifier = Modifier
.fillMaxWidth()
.clip(RoundedCornerShape(10.dp))
.height(200.dp)
.background(
color = backgroundColor,
shape = RoundedCornerShape(14.dp)
)
) {
Image(
painter = painterResource(id = imageId), // 대체 이미지
contentDescription = null,
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight()
.padding(horizontal = 15.dp)
.padding(bottom = 80.dp)
.padding(top = 15.dp)
)
}
}

@Preview(showBackground = true)
@Composable
fun DetailRecommendedItemPreview() {
AlddeulBabsangTheme {
DetailRecommendedItem(
data = BabsangRecommendEntity(
id = 1,
avatar = null,
data = ResponseDetailRecommendDto(
storeId = 1,
name = "족발 야시장",
codeName = "한식",
address = "용산 동자동",
category = "한식",
region = "용산구",
)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.foundation.lazy.grid.itemsIndexed
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
Expand Down Expand Up @@ -49,17 +49,19 @@ 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.component.LoadingCircleIndicator
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
import com.hackathon.alddeul_babsang.core_ui.theme.Gray500
import com.hackathon.alddeul_babsang.core_ui.theme.Gray900
import com.hackathon.alddeul_babsang.core_ui.theme.Orange400
import com.hackathon.alddeul_babsang.core_ui.theme.Orange700
import com.hackathon.alddeul_babsang.core_ui.theme.Orange900
import com.hackathon.alddeul_babsang.core_ui.theme.Red
import com.hackathon.alddeul_babsang.core_ui.theme.White
import com.hackathon.alddeul_babsang.core_ui.theme.body4Semi
import com.hackathon.alddeul_babsang.core_ui.theme.head4Bold
import com.hackathon.alddeul_babsang.core_ui.theme.head6Semi
import com.hackathon.alddeul_babsang.core_ui.theme.head7Regular
import com.hackathon.alddeul_babsang.core_ui.theme.head7Semi
import com.hackathon.alddeul_babsang.data.dto.response.ResponseDetailDto
Expand Down Expand Up @@ -87,6 +89,7 @@ fun DetailRoute(
LaunchedEffect(Unit) {
detailViewModel.getReviews(id)
detailViewModel.postDetail(id.toInt())
detailViewModel.postDetailRecommend(id.toInt())
}

when (postDetailState) {
Expand Down Expand Up @@ -125,6 +128,10 @@ fun DetailScreen(
val getReviewsState by detailViewModel.getReviewsState.collectAsStateWithLifecycle(UiState.Empty)
val likeViewModel: LikeViewModel = hiltViewModel()

val postDetailRecommendState by detailViewModel.postDetailRecommendState.collectAsStateWithLifecycle(
UiState.Empty
)

Scaffold(
modifier = Modifier.fillMaxSize(),
topBar = {
Expand Down Expand Up @@ -345,24 +352,57 @@ fun DetailScreen(
color = Gray900
)
}
item {
LazyVerticalGrid(
contentPadding = PaddingValues(horizontal = 20.dp),
columns = GridCells.Fixed(2),
modifier = Modifier
.fillMaxWidth()
.height(550.dp),
horizontalArrangement = Arrangement.spacedBy(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
items(detailViewModel.mockDetailRecommend) { item ->
DetailRecommendedItem(
data = item,
onClick = { onItemClick(item.id) }


when (postDetailRecommendState) {
is UiState.Loading -> {
item {
LoadingCircleIndicator()
}
}

is UiState.Success -> {
val data = (postDetailRecommendState as UiState.Success).data
if (data.isEmpty()) {
} else {
item {
LazyVerticalGrid(
contentPadding = PaddingValues(horizontal = 20.dp),
columns = GridCells.Fixed(2),
modifier = Modifier
.fillMaxWidth()
.height(550.dp),
horizontalArrangement = Arrangement.spacedBy(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
itemsIndexed(data) { index, item ->
DetailRecommendedItem(
onClick = { onItemClick(item.storeId) },
data = item
)
}
}
}
}


}

is UiState.Failure -> {
item {
Text(
text = (postDetailRecommendState as UiState.Failure).msg,
style = head6Semi,
color = Orange900,
modifier = Modifier.padding(vertical = 20.dp)
)
}
}

else -> {}

}

}
}
}
Loading

0 comments on commit c90b06f

Please sign in to comment.