Skip to content

Commit c8f7f14

Browse files
authored
[Feat/#94] 굿즈별 페이지 API 연동
1 parent 3c972d8 commit c8f7f14

26 files changed

+570
-259
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.poti.android.data.mapper.party
2+
3+
import com.poti.android.data.remote.dto.response.party.PartyDto
4+
import com.poti.android.data.remote.dto.response.party.ProductPartyListResponseDto
5+
import com.poti.android.domain.model.party.PartySummary
6+
import com.poti.android.domain.model.party.ProductPartyList
7+
8+
fun ProductPartyListResponseDto.toDomain(): ProductPartyList =
9+
ProductPartyList(
10+
partyTitle = postTitle,
11+
artistName = artist,
12+
partySummaries = pots.map { it.toDomain() },
13+
)
14+
15+
private fun PartyDto.toDomain(): PartySummary =
16+
PartySummary(
17+
partyId = potId,
18+
price = price,
19+
goodsImageUrl = thumbnailUrl.orEmpty(),
20+
currentCount = currentCount,
21+
totalCount = totalCount,
22+
availableMembers = availableMembers,
23+
profileImageUrl = uploader.profileImage,
24+
nickname = uploader.nickname,
25+
rating = uploader.rating,
26+
)

app/src/main/java/com/poti/android/data/remote/datasource/PartyRemoteDataSource.kt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import com.poti.android.data.remote.dto.response.party.MyRecruitListDto
1111
import com.poti.android.data.remote.dto.response.party.PartyDetailResponseDto
1212
import com.poti.android.data.remote.dto.response.party.PartyJoinOptionsDto
1313
import com.poti.android.data.remote.dto.response.party.PartyJoinResponseDto
14+
import com.poti.android.data.remote.dto.response.party.ProductPartyListResponseDto
1415
import com.poti.android.data.remote.dto.response.party.ProductSearchResponseDto
1516
import com.poti.android.data.remote.dto.response.party.ShippingOptionResponseDto
1617
import com.poti.android.data.remote.service.PartyService
@@ -51,4 +52,21 @@ class PartyRemoteDataSource @Inject constructor(
5152

5253
suspend fun getRecruitPostParticipant(postId: Long): BaseResponse<GroupBuyPostParticipantDetailDto> =
5354
partyService.getRecruitPostParticipant(postId)
55+
56+
suspend fun getProductPartyList(
57+
page: Int?,
58+
size: Int?,
59+
title: String,
60+
artistId: Long,
61+
sort: String,
62+
memberIds: List<Long>?,
63+
): BaseResponse<ProductPartyListResponseDto> =
64+
partyService.getProductPartyList(
65+
page = page,
66+
size = size,
67+
title = title,
68+
artistId = artistId,
69+
sort = sort,
70+
memberIds = memberIds,
71+
)
5472
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package com.poti.android.data.remote.dto.response.party
2+
3+
import kotlinx.serialization.SerialName
4+
import kotlinx.serialization.Serializable
5+
6+
@Serializable
7+
data class ProductPartyListResponseDto(
8+
@SerialName("postTitle")
9+
val postTitle: String,
10+
@SerialName("artistId")
11+
val artistId: Long,
12+
@SerialName("artist")
13+
val artist: String,
14+
@SerialName("currentPage")
15+
val currentPage: Int,
16+
@SerialName("hasNext")
17+
val hasNext: Boolean,
18+
@SerialName("pots")
19+
val pots: List<PartyDto>,
20+
)
21+
22+
@Serializable
23+
data class PartyDto(
24+
@SerialName("potId")
25+
val potId: Long,
26+
@SerialName("price")
27+
val price: Int,
28+
@SerialName("thumbnailUrl")
29+
val thumbnailUrl: String?,
30+
@SerialName("currentCount")
31+
val currentCount: Int,
32+
@SerialName("totalCount")
33+
val totalCount: Int,
34+
@SerialName("status")
35+
val status: String,
36+
@SerialName("availableMembers")
37+
val availableMembers: List<String>,
38+
@SerialName("uploader")
39+
val uploader: PartyUploaderDto,
40+
)
41+
42+
@Serializable
43+
data class PartyUploaderDto(
44+
@SerialName("userId")
45+
val userId: Long,
46+
@SerialName("nickname")
47+
val nickname: String,
48+
@SerialName("profileImage")
49+
val profileImage: String?,
50+
@SerialName("rating")
51+
val rating: Double,
52+
)

app/src/main/java/com/poti/android/data/remote/service/PartyService.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import com.poti.android.data.remote.dto.response.party.MyRecruitListDto
1111
import com.poti.android.data.remote.dto.response.party.PartyDetailResponseDto
1212
import com.poti.android.data.remote.dto.response.party.PartyJoinOptionsDto
1313
import com.poti.android.data.remote.dto.response.party.PartyJoinResponseDto
14+
import com.poti.android.data.remote.dto.response.party.ProductPartyListResponseDto
1415
import com.poti.android.data.remote.dto.response.party.ProductSearchResponseDto
1516
import com.poti.android.data.remote.dto.response.party.ShippingOptionResponseDto
1617
import retrofit2.http.Body
@@ -68,4 +69,14 @@ interface PartyService {
6869
suspend fun getRecruitPostParticipant(
6970
@Path("postId") postId: Long,
7071
): BaseResponse<GroupBuyPostParticipantDetailDto>
72+
73+
@GET("/api/v1/posts/pots")
74+
suspend fun getProductPartyList(
75+
@Query("page") page: Int?,
76+
@Query("size") size: Int?,
77+
@Query("title") title: String,
78+
@Query("artistId") artistId: Long,
79+
@Query("sort") sort: String,
80+
@Query("memberIds") memberIds: List<Long>?,
81+
): BaseResponse<ProductPartyListResponseDto>
7182
}

app/src/main/java/com/poti/android/data/repository/PartyRepositoryImpl.kt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import com.poti.android.domain.model.history.RecruiterDetail
2020
import com.poti.android.domain.model.party.PartyDetail
2121
import com.poti.android.domain.model.party.PartyJoinInfo
2222
import com.poti.android.domain.model.party.PartyJoinOption
23+
import com.poti.android.domain.model.party.ProductPartyList
2324
import com.poti.android.domain.repository.PartyRepository
2425
import javax.inject.Inject
2526

@@ -124,4 +125,25 @@ class PartyRepositoryImpl @Inject constructor(
124125
.getOrThrow()
125126
.toDomain()
126127
}
128+
129+
override suspend fun getProductPartyList(
130+
page: Int?,
131+
size: Int?,
132+
title: String,
133+
artistId: Long,
134+
sort: String,
135+
memberIds: List<Long>?,
136+
): Result<ProductPartyList> = httpResponseHandler.safeApiCall {
137+
partyRemoteDataSource.getProductPartyList(
138+
page = page,
139+
size = size,
140+
title = title,
141+
artistId = artistId,
142+
sort = sort,
143+
memberIds = memberIds,
144+
)
145+
.handleApiResponse()
146+
.getOrThrow()
147+
.toDomain()
148+
}
127149
}

app/src/main/java/com/poti/android/domain/model/party/PartyList.kt renamed to app/src/main/java/com/poti/android/domain/model/party/ProductPartyList.kt

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package com.poti.android.domain.model.party
22

3-
import com.poti.android.domain.model.artist.Member
4-
5-
data class PartyList(
3+
data class ProductPartyList(
64
val partyTitle: String,
75
val artistName: String,
86
val partySummaries: List<PartySummary>,
@@ -14,7 +12,7 @@ data class PartySummary(
1412
val goodsImageUrl: String,
1513
val currentCount: Int,
1614
val totalCount: Int,
17-
val availableMembers: List<Member>,
15+
val availableMembers: List<String>,
1816
val profileImageUrl: String?,
1917
val nickname: String,
2018
val rating: Double,

app/src/main/java/com/poti/android/domain/repository/PartyRepository.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import com.poti.android.domain.model.history.RecruiterDetail
99
import com.poti.android.domain.model.party.PartyDetail
1010
import com.poti.android.domain.model.party.PartyJoinInfo
1111
import com.poti.android.domain.model.party.PartyJoinOption
12+
import com.poti.android.domain.model.party.ProductPartyList
1213

1314
interface PartyRepository {
1415
suspend fun searchProductTitle(
@@ -45,4 +46,13 @@ interface PartyRepository {
4546
suspend fun getRecruitDetail(postId: Long): Result<RecruiterDetail>
4647

4748
suspend fun getRecruitPostParticipant(postId: Long): Result<ParticipantManageDetail>
49+
50+
suspend fun getProductPartyList(
51+
page: Int?,
52+
size: Int?,
53+
title: String,
54+
artistId: Long,
55+
sort: String,
56+
memberIds: List<Long>?,
57+
): Result<ProductPartyList>
4858
}

app/src/main/java/com/poti/android/presentation/party/goodsfilter/DummyPotsDate.kt

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
package com.poti.android.presentation.party.goodsfilter
22

3-
import com.poti.android.domain.model.artist.Member
4-
import com.poti.android.domain.model.party.PartyList
53
import com.poti.android.domain.model.party.PartySummary
4+
import com.poti.android.domain.model.party.ProductPartyList
65

7-
val dummyPartyList = PartyList(
6+
val dummyProductPartyList = ProductPartyList(
87
partyTitle = "러브다이브 위드뮤",
98
artistName = "IVE(아이브)",
109
partySummaries = listOf(
@@ -14,10 +13,7 @@ val dummyPartyList = PartyList(
1413
goodsImageUrl = "",
1514
currentCount = 3,
1615
totalCount = 5,
17-
availableMembers = listOf(
18-
Member(1, "원영"),
19-
Member(2, "유진"),
20-
),
16+
availableMembers = listOf("원영", "유진"),
2117
profileImageUrl = "",
2218
nickname = "포티공주",
2319
rating = 4.8,
@@ -28,10 +24,7 @@ val dummyPartyList = PartyList(
2824
goodsImageUrl = "",
2925
currentCount = 6,
3026
totalCount = 6,
31-
availableMembers = listOf(
32-
Member(1, "원영"),
33-
Member(2, "유진"),
34-
),
27+
availableMembers = listOf("원영", "유진"),
3528
profileImageUrl = "",
3629
nickname = "굿즈요정",
3730
rating = 4.5,
@@ -42,10 +35,7 @@ val dummyPartyList = PartyList(
4235
goodsImageUrl = "",
4336
currentCount = 1,
4437
totalCount = 4,
45-
availableMembers = listOf(
46-
Member(1, "가을"),
47-
Member(2, "이서"),
48-
),
38+
availableMembers = listOf("원영", "유진"),
4939
profileImageUrl = "",
5040
nickname = "공구마스터",
5141
rating = 5.0,

app/src/main/java/com/poti/android/presentation/party/goodsfilter/GoodsCategoryScreen.kt

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ fun GoodsCategoryRoute(
3838
artistId: Long,
3939
onPopBackStack: () -> Unit,
4040
onNavigateToPartyCreate: () -> Unit,
41-
onNavigateToGoodsPartyList: (Long) -> Unit,
41+
onNavigateToGoodsPartyList: (Long, String) -> Unit,
4242
modifier: Modifier = Modifier,
4343
viewModel: GoodsCategoryViewModel = hiltViewModel(),
4444
) {
@@ -48,7 +48,7 @@ fun GoodsCategoryRoute(
4848
when (effect) {
4949
GoodsCategoryUiEffect.NavigateBack -> onPopBackStack()
5050
GoodsCategoryUiEffect.NavigateToPartyCreate -> onNavigateToPartyCreate()
51-
GoodsCategoryUiEffect.NavigateToGoodsFilter -> onNavigateToGoodsPartyList(artistId)
51+
is GoodsCategoryUiEffect.NavigateToGoodsPartyList -> onNavigateToGoodsPartyList(artistId, effect.title)
5252
}
5353
}
5454

@@ -72,8 +72,8 @@ fun GoodsCategoryRoute(
7272
onSortDismiss = {
7373
viewModel.processIntent(GoodsCategoryUiIntent.OnSortDismiss)
7474
},
75-
onCardClick = {
76-
viewModel.processIntent(GoodsCategoryUiIntent.OnCardClick)
75+
onCardClick = { artistId, title ->
76+
viewModel.processIntent(GoodsCategoryUiIntent.OnCardClick(artistId, title))
7777
},
7878
modifier = modifier,
7979
)
@@ -90,7 +90,7 @@ private fun GoodsCategoryScreen(
9090
onSortFilterClick: () -> Unit,
9191
onSortSelect: (GoodsSortType) -> Unit,
9292
onSortDismiss: () -> Unit,
93-
onCardClick: () -> Unit,
93+
onCardClick: (Long, String) -> Unit,
9494
modifier: Modifier = Modifier,
9595
) {
9696
if (isSortBottomSheetVisible) {
@@ -139,10 +139,11 @@ private fun GoodsCategoryScreen(
139139
title = groupItem.postTitle,
140140
partyCount = groupItem.postCount,
141141
tag = groupItem.tag,
142-
onClick = onCardClick, // TODO: [예림] 굿즈별 페이지로 이동; 타이틀, 아티스트 아이디
142+
onClick = { id, title -> onCardClick(id, title) },
143143
modifier = Modifier
144144
.fillMaxWidth()
145145
.padding(bottom = 16.dp),
146+
artistId = groupItem.artistId,
146147
)
147148
}
148149
item {
@@ -165,7 +166,7 @@ private fun GoodsCategoryScreenPreview() {
165166
onSortFilterClick = {},
166167
onSortSelect = {},
167168
onSortDismiss = {},
168-
onCardClick = {},
169+
onCardClick = { _, _ -> },
169170
)
170171
}
171172
}

app/src/main/java/com/poti/android/presentation/party/goodsfilter/GoodsCategoryViewModel.kt

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,9 @@ class GoodsCategoryViewModel @Inject constructor(
2323

2424
override fun processIntent(intent: GoodsCategoryUiIntent) {
2525
when (intent) {
26-
GoodsCategoryUiIntent.OnBackClick ->
27-
sendEffect(GoodsCategoryUiEffect.NavigateBack)
28-
29-
GoodsCategoryUiIntent.OnFloatingClick ->
30-
sendEffect(GoodsCategoryUiEffect.NavigateToPartyCreate)
31-
32-
GoodsCategoryUiIntent.OnSortFilterClick -> {
33-
updateState { copy(isSortBottomSheetVisible = true) }
34-
}
35-
26+
GoodsCategoryUiIntent.OnBackClick -> sendEffect(GoodsCategoryUiEffect.NavigateBack)
27+
GoodsCategoryUiIntent.OnFloatingClick -> sendEffect(GoodsCategoryUiEffect.NavigateToPartyCreate)
28+
GoodsCategoryUiIntent.OnSortFilterClick -> updateState { copy(isSortBottomSheetVisible = true) }
3629
is GoodsCategoryUiIntent.OnSortSelected -> {
3730
updateState {
3831
copy(
@@ -42,13 +35,8 @@ class GoodsCategoryViewModel @Inject constructor(
4235
}
4336
loadGoodsCategoryList(intent.sortType)
4437
}
45-
46-
GoodsCategoryUiIntent.OnSortDismiss -> {
47-
updateState { copy(isSortBottomSheetVisible = false) }
48-
}
49-
50-
GoodsCategoryUiIntent.OnCardClick ->
51-
sendEffect(GoodsCategoryUiEffect.NavigateToGoodsFilter)
38+
GoodsCategoryUiIntent.OnSortDismiss -> updateState { copy(isSortBottomSheetVisible = false) }
39+
is GoodsCategoryUiIntent.OnCardClick -> sendEffect(GoodsCategoryUiEffect.NavigateToGoodsPartyList(intent.artistId, intent.title))
5240
}
5341
}
5442

0 commit comments

Comments
 (0)