Skip to content

Commit 663b80e

Browse files
authored
[Feat/#73] 프로필 API 연동
1 parent d1e3c55 commit 663b80e

File tree

9 files changed

+127
-47
lines changed

9 files changed

+127
-47
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
2+
3+
import com.poti.android.data.remote.dto.response.user.ProfileResponseDto
4+
import com.poti.android.data.remote.dto.response.user.RecruitSummaryDto
5+
import com.poti.android.domain.model.user.HistorySummary
6+
import com.poti.android.domain.model.user.UserProfile
7+
8+
fun ProfileResponseDto.toDomain(): UserProfile =
9+
UserProfile(
10+
userId = userId,
11+
email = email,
12+
nickname = nickname,
13+
profileImageUrl = profileImageUrl,
14+
ratingAvg = ratingAvg,
15+
activityMessage = activityMessage,
16+
joinedAt = joinedAt,
17+
hasFavoriteArtist = hasFavoriteArtist,
18+
recruitSummary = recruitSummary.toDomain(),
19+
)
20+
21+
fun RecruitSummaryDto.toDomain(): HistorySummary =
22+
HistorySummary(
23+
total = total,
24+
inProgress = inProgress,
25+
completed = completed,
26+
)

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import com.poti.android.data.remote.dto.request.user.OnboardingRequestDto
66
import com.poti.android.data.remote.dto.response.user.MyPageResponseDto
77
import com.poti.android.data.remote.dto.response.user.NicknameDuplicateResponseDto
88
import com.poti.android.data.remote.dto.response.user.OnboardingResponseDto
9+
import com.poti.android.data.remote.dto.response.user.ProfileResponseDto
910
import com.poti.android.data.remote.service.UserService
1011
import javax.inject.Inject
1112

@@ -20,4 +21,7 @@ class UserRemoteDataSource @Inject constructor(
2021

2122
suspend fun getUserMyPage(): BaseResponse<MyPageResponseDto> =
2223
userService.getUserMyPage()
24+
25+
suspend fun getUserProfile(userId: Long): BaseResponse<ProfileResponseDto> =
26+
userService.getUserProfile(userId)
2327
}

app/src/main/java/com/poti/android/data/remote/dto/response/user/MyPageResponseDto.kt

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -28,23 +28,3 @@ data class MyPageResponseDto(
2828
@SerialName("recruitSummary")
2929
val recruitSummary: RecruitSummaryDto,
3030
)
31-
32-
@Serializable
33-
data class ParticipationSummaryDto(
34-
@SerialName("total")
35-
val total: Int,
36-
@SerialName("inProgress")
37-
val inProgress: Int,
38-
@SerialName("completed")
39-
val completed: Int,
40-
)
41-
42-
@Serializable
43-
data class RecruitSummaryDto(
44-
@SerialName("total")
45-
val total: Int,
46-
@SerialName("inProgress")
47-
val inProgress: Int,
48-
@SerialName("completed")
49-
val completed: Int,
50-
)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.poti.android.data.remote.dto.response.user
2+
3+
import kotlinx.serialization.SerialName
4+
import kotlinx.serialization.Serializable
5+
6+
@Serializable
7+
data class ProfileResponseDto(
8+
@SerialName("userId")
9+
val userId: Long,
10+
@SerialName("email")
11+
val email: String,
12+
@SerialName("nickname")
13+
val nickname: String,
14+
@SerialName("profileImageUrl")
15+
val profileImageUrl: String,
16+
@SerialName("ratingAvg")
17+
val ratingAvg: Double,
18+
@SerialName("activityMessage")
19+
val activityMessage: String,
20+
@SerialName("joinedAt")
21+
val joinedAt: String,
22+
@SerialName("hasFavoriteArtist")
23+
val hasFavoriteArtist: Boolean,
24+
@SerialName("recruitSummary")
25+
val recruitSummary: RecruitSummaryDto,
26+
)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.poti.android.data.remote.dto.response.user
2+
3+
import kotlinx.serialization.SerialName
4+
import kotlinx.serialization.Serializable
5+
6+
@Serializable
7+
data class ParticipationSummaryDto(
8+
@SerialName("total")
9+
val total: Int,
10+
@SerialName("inProgress")
11+
val inProgress: Int,
12+
@SerialName("completed")
13+
val completed: Int,
14+
)
15+
16+
@Serializable
17+
data class RecruitSummaryDto(
18+
@SerialName("total")
19+
val total: Int,
20+
@SerialName("inProgress")
21+
val inProgress: Int,
22+
@SerialName("completed")
23+
val completed: Int,
24+
)

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ import com.poti.android.data.remote.dto.request.user.OnboardingRequestDto
66
import com.poti.android.data.remote.dto.response.user.MyPageResponseDto
77
import com.poti.android.data.remote.dto.response.user.NicknameDuplicateResponseDto
88
import com.poti.android.data.remote.dto.response.user.OnboardingResponseDto
9+
import com.poti.android.data.remote.dto.response.user.ProfileResponseDto
910
import retrofit2.http.Body
1011
import retrofit2.http.GET
1112
import retrofit2.http.PATCH
1213
import retrofit2.http.POST
14+
import retrofit2.http.Path
1315

1416
interface UserService {
1517
@PATCH("/api/v1/users/onboarding")
@@ -24,4 +26,9 @@ interface UserService {
2426

2527
@GET("/api/v1/users/mypage")
2628
suspend fun getUserMyPage(): BaseResponse<MyPageResponseDto>
29+
30+
@GET("/api/v1/users/{userId}/profile")
31+
suspend fun getUserProfile(
32+
@Path("userId") userId: Long,
33+
): BaseResponse<ProfileResponseDto>
2734
}

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ package com.poti.android.data.repository
33
import com.poti.android.core.network.model.handleApiResponse
44
import com.poti.android.core.network.util.HttpResponseHandler
55
import com.poti.android.data.mapper.artist.toDomain
6+
import com.poti.android.data.mapper.toDomain
67
import com.poti.android.data.mapper.user.toDomain
78
import com.poti.android.data.remote.datasource.UserRemoteDataSource
89
import com.poti.android.data.remote.dto.request.user.NicknameDuplicateRequestDto
910
import com.poti.android.data.remote.dto.request.user.OnboardingRequestDto
1011
import com.poti.android.domain.model.user.UserMyPage
12+
import com.poti.android.domain.model.user.UserProfile
1113
import com.poti.android.domain.repository.UserRepository
1214
import javax.inject.Inject
1315

@@ -44,4 +46,11 @@ class UserRepositoryImpl @Inject constructor(
4446
.getOrThrow()
4547
.toDomain()
4648
}
49+
50+
override suspend fun getUserProfile(userId: Long): Result<UserProfile> = httpResponseHandler.safeApiCall {
51+
userRemoteDataSource.getUserProfile(userId)
52+
.handleApiResponse()
53+
.getOrThrow()
54+
.toDomain()
55+
}
4756
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.poti.android.domain.repository
22

33
import com.poti.android.domain.model.user.UserMyPage
4+
import com.poti.android.domain.model.user.UserProfile
45

56
interface UserRepository {
67
suspend fun patchOnboarding(
@@ -13,4 +14,8 @@ interface UserRepository {
1314
): Result<Boolean>
1415

1516
suspend fun getUserMyPage(): Result<UserMyPage>
17+
18+
suspend fun getUserProfile(
19+
userId: Long,
20+
): Result<UserProfile>
1621
}
Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,26 @@
11
package com.poti.android.presentation.user.profile
22

3+
import androidx.lifecycle.SavedStateHandle
4+
import androidx.navigation.toRoute
35
import com.poti.android.core.base.BaseViewModel
46
import com.poti.android.core.common.state.ApiState
5-
import com.poti.android.domain.model.user.HistorySummary
6-
import com.poti.android.domain.model.user.UserProfile
7+
import com.poti.android.domain.repository.UserRepository
78
import com.poti.android.presentation.user.profile.model.ProfileUiEffect
89
import com.poti.android.presentation.user.profile.model.ProfileUiIntent
910
import com.poti.android.presentation.user.profile.model.ProfileUiState
11+
import com.poti.android.presentation.user.profile.navigation.ProfileRoute
1012
import dagger.hilt.android.lifecycle.HiltViewModel
1113
import javax.inject.Inject
1214

1315
@HiltViewModel
14-
class ProfileViewModel @Inject constructor() : BaseViewModel<ProfileUiState, ProfileUiIntent, ProfileUiEffect>(
15-
initialState = ProfileUiState(),
16-
) {
16+
class ProfileViewModel @Inject constructor(
17+
private val userRepository: UserRepository,
18+
savedStateHandle: SavedStateHandle,
19+
) : BaseViewModel<ProfileUiState, ProfileUiIntent, ProfileUiEffect>(
20+
initialState = ProfileUiState(),
21+
) {
22+
private val userId = savedStateHandle.toRoute<ProfileRoute.Profile>().userId
23+
1724
override fun processIntent(intent: ProfileUiIntent) {
1825
when (intent) {
1926
ProfileUiIntent.OnBackClick -> sendEffect(ProfileUiEffect.NavigateBack)
@@ -24,27 +31,19 @@ class ProfileViewModel @Inject constructor() : BaseViewModel<ProfileUiState, Pro
2431
loadUserProfile()
2532
}
2633

27-
private fun loadUserProfile() {
28-
updateState {
29-
copy(
30-
userProfileLoadState = ApiState.Success(
31-
UserProfile(
32-
userId = 1L,
33-
email = "akkma@app.jam",
34-
nickname = "분철의 악마",
35-
profileImageUrl = "",
36-
ratingAvg = 4.8,
37-
activityMessage = "최근 3일 이내 활동",
38-
joinedAt = "2025-12-28",
39-
hasFavoriteArtist = true,
40-
recruitSummary = HistorySummary(
41-
total = 7,
42-
inProgress = 2,
43-
completed = 5,
44-
),
45-
),
46-
),
47-
)
48-
}
34+
private fun loadUserProfile() = launchScope {
35+
userRepository.getUserProfile(userId = userId)
36+
.onSuccess { userProfile ->
37+
updateState {
38+
copy(userProfileLoadState = ApiState.Success(userProfile))
39+
}
40+
}
41+
.onFailure { throwable ->
42+
updateState {
43+
copy(
44+
userProfileLoadState = ApiState.Failure(throwable.message ?: "Failed"),
45+
)
46+
}
47+
}
4948
}
5049
}

0 commit comments

Comments
 (0)