Skip to content

Commit

Permalink
Merge pull request #65 from YAPP-Github/feature/TNT-115
Browse files Browse the repository at this point in the history
[TNT-115] 트레이너, 트레이니 연결 기능 구현
  • Loading branch information
SeonJeongk authored Feb 7, 2025
2 parents 105945e + 53f1096 commit 1fcce19
Show file tree
Hide file tree
Showing 55 changed files with 945 additions and 368 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ fun TnTSingleButtonPopupDialog(
)
TnTTextButton(
size = ButtonSize.Medium,
type = ButtonType.Gray,
type = ButtonType.Primary,
text = buttonText,
onClick = onButtonClick,
modifier = Modifier
Expand Down Expand Up @@ -230,6 +230,7 @@ fun TnTIconSingleButtonPopupDialog(
topIcon: Painter,
buttonText: String,
modifier: Modifier = Modifier,
type: ButtonType = ButtonType.Gray,
onButtonClick: () -> Unit,
onDismiss: () -> Unit,
) {
Expand Down Expand Up @@ -273,7 +274,7 @@ fun TnTIconSingleButtonPopupDialog(
)
TnTTextButton(
size = ButtonSize.Medium,
type = ButtonType.Gray,
type = type,
text = buttonText,
onClick = onButtonClick,
modifier = Modifier
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,13 @@ sealed interface Route {
val email: String,
) : Route

@Serializable
data class TrainerInvite(val isSkippable: Boolean) : Route

@Serializable
data class TrainerConnect(
val isSkippable: Boolean,
val isCompleted: Boolean,
val trainerId: String,
val traineeId: String,
) : Route

@Serializable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ package co.kr.tnt.ui.model
import androidx.annotation.DrawableRes
import co.kr.tnt.core.ui.R
import co.kr.tnt.domain.model.User
import co.kr.tnt.domain.model.UserType

sealed class DefaultUserProfile(
@DrawableRes val image: Int,
) {
data object Trainer : DefaultUserProfile(
image = R.drawable.img_default_profile_trainer,
)

data object Trainee : DefaultUserProfile(
image = R.drawable.img_default_profile_trainee,
)
Expand All @@ -21,5 +23,12 @@ sealed class DefaultUserProfile(
is User.Trainer -> Trainee
}
}

fun fromDomain(type: UserType): DefaultUserProfile {
return when (type) {
UserType.TRAINER -> Trainer
UserType.TRAINEE -> Trainee
}
}
}
}
1 change: 1 addition & 0 deletions core/ui/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<string name="ok">확인</string>

<string name="error_server_request_failed">서버 요청에 실패했어요</string>
<string name="entered_wrong_text">잘못된 수치를 입력했어요</string>

<string name="trainee">트레이니</string>
<string name="trainer">트레이너</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
internal object NetworkModule {
private const val TIME_OUT_SECONDS: Long = 10
private const val CONNECT_TIMEOUT_SECONDS: Long = 10
private const val READ_WRITE_TIMEOUT_SECONDS: Long = 20

@Provides
@Singleton
Expand All @@ -43,8 +44,9 @@ internal object NetworkModule {
loggingInterceptor: HttpLoggingInterceptor,
authenticator: Authenticator,
): OkHttpClient = OkHttpClient.Builder()
.connectTimeout(TIME_OUT_SECONDS, TimeUnit.SECONDS)
.readTimeout(TIME_OUT_SECONDS, TimeUnit.SECONDS)
.connectTimeout(CONNECT_TIMEOUT_SECONDS, TimeUnit.SECONDS)
.readTimeout(READ_WRITE_TIMEOUT_SECONDS, TimeUnit.SECONDS)
.writeTimeout(READ_WRITE_TIMEOUT_SECONDS, TimeUnit.SECONDS)
.addInterceptor(sessionInterceptor)
.addInterceptor(loggingInterceptor)
.authenticator(authenticator)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package co.kr.data.network.model

import kotlinx.serialization.Serializable

@Serializable
data class ConnectRequest(
val invitationCode: String,
val startDate: String,
val totalPtCount: Int,
val finishedPtCount: Int,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package co.kr.data.network.model

import co.kr.tnt.domain.model.ConnectRequestResult
import kotlinx.serialization.Serializable

@Serializable
data class ConnectRequestResponse(
val trainerName: String,
val traineeName: String,
val trainerProfileImageUrl: String,
val traineeProfileImageUrl: String,
)

fun ConnectRequestResponse.toDomain(): ConnectRequestResult =
ConnectRequestResult(
trainerName = trainerName,
traineeName = traineeName,
trainerImage = trainerProfileImageUrl,
traineeImage = traineeProfileImageUrl,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package co.kr.data.network.model

import co.kr.tnt.domain.model.ConnectedResult
import kotlinx.serialization.Serializable

@Serializable
data class ConnectedTraineeResponse(
val trainerName: String,
val traineeName: String,
val trainerProfileImageUrl: String?,
val traineeProfileImageUrl: String?,
val traineeAge: Int,
val height: Double,
val weight: Double,
val ptGoal: String,
val cautionNote: String?,
)

fun ConnectedTraineeResponse.toDomain(): ConnectedResult =
ConnectedResult(
trainerName = trainerName,
traineeName = traineeName,
trainerImage = trainerProfileImageUrl,
traineeImage = traineeProfileImageUrl,
age = traineeAge,
height = height,
weight = weight,
ptGoal = ptGoal,
cautionNote = cautionNote,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package co.kr.data.network.model

import co.kr.tnt.domain.model.InviteCodeResult
import kotlinx.serialization.Serializable

@Serializable
data class InviteCodeResponse(
val invitationCode: String,
)

fun InviteCodeResponse.toDomain(): InviteCodeResult {
return InviteCodeResult(
invitationCode = invitationCode,
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package co.kr.data.network.model

import kotlinx.serialization.Serializable

@Serializable
data class VerifyCodeResponse(
val isVerified: Boolean,
)
Original file line number Diff line number Diff line change
@@ -1,31 +1,64 @@
package co.kr.data.network.service

import co.kr.data.network.model.CheckSessionResponse
import co.kr.data.network.model.ConnectRequest
import co.kr.data.network.model.ConnectRequestResponse
import co.kr.data.network.model.ConnectedTraineeResponse
import co.kr.data.network.model.InviteCodeResponse
import co.kr.data.network.model.LoginRequest
import co.kr.data.network.model.LoginResponse
import co.kr.data.network.model.SignUpResponse
import co.kr.data.network.model.VerifyCodeResponse
import co.kr.data.network.util.WithoutSessionCheckPath.CHECK_SESSION_PATH
import okhttp3.MultipartBody
import okhttp3.RequestBody
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.Multipart
import retrofit2.http.POST
import retrofit2.http.PUT
import retrofit2.http.Part
import retrofit2.http.Path
import retrofit2.http.Query

interface ApiService {
@GET(CHECK_SESSION_PATH)
suspend fun getCheckSession(): CheckSessionResponse

// Login
@POST("/login")
suspend fun postLogin(
@Body request: LoginRequest,
): LoginResponse

// SignUp
@Multipart
@POST("/members/sign-up")
suspend fun postSignUp(
@Part profileImage: MultipartBody.Part?,
@Part("request") request: RequestBody,
): SignUpResponse

// Connect
@GET("/trainers/invitation-code")
suspend fun getInviteCode(): InviteCodeResponse

@PUT("/trainers/invitation-code/reissue")
suspend fun regenerateInviteCode(): InviteCodeResponse

@GET("/trainers/invitation-code/verify/{code}")
suspend fun getVerifyInviteCode(
@Path("code") code: String,
): VerifyCodeResponse

@POST("/trainees/connect-trainer")
suspend fun postConnectRequest(
@Body request: ConnectRequest,
): ConnectRequestResponse

@GET("/trainers/first-connected-trainee")
suspend fun getConnectedTraineeInfo(
@Query("trainerId") trainerId: String,
@Query("traineeId") traineeId: String,
): ConnectedTraineeResponse
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package co.kr.data.network.source

import co.kr.data.network.model.ConnectRequest
import co.kr.data.network.model.ConnectRequestResponse
import co.kr.data.network.model.ConnectedTraineeResponse
import co.kr.data.network.model.InviteCodeResponse
import co.kr.data.network.model.VerifyCodeResponse
import co.kr.data.network.service.ApiService
import co.kr.data.network.util.networkHandler
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class ConnectRemoteDataSource @Inject constructor(
private val apiService: ApiService,
) {
suspend fun getInviteCode(): InviteCodeResponse = networkHandler {
apiService.getInviteCode()
}

suspend fun regenerateInviteCode(): InviteCodeResponse = networkHandler {
apiService.regenerateInviteCode()
}

suspend fun getVerifyInviteCode(code: String): VerifyCodeResponse = networkHandler {
apiService.getVerifyInviteCode(code = code)
}

suspend fun connectRequest(connectRequest: ConnectRequest): ConnectRequestResponse =
networkHandler {
apiService.postConnectRequest(request = connectRequest)
}

suspend fun getConnectedTraineeInfo(
trainerId: String,
traineeId: String,
): ConnectedTraineeResponse = networkHandler {
apiService.getConnectedTraineeInfo(
trainerId = trainerId,
traineeId = traineeId,
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package co.kr.data.repository

import co.kr.data.network.model.ConnectRequest
import co.kr.data.network.model.toDomain
import co.kr.data.network.source.ConnectRemoteDataSource
import co.kr.tnt.domain.model.ConnectRequestResult
import co.kr.tnt.domain.model.ConnectedResult
import co.kr.tnt.domain.model.InviteCodeResult
import co.kr.tnt.domain.repository.ConnectRepository
import javax.inject.Inject

class ConnectRepositoryImpl @Inject constructor(
private val connectRemoteDataSource: ConnectRemoteDataSource,
) : ConnectRepository {
override suspend fun getInviteCode(): InviteCodeResult {
val response = connectRemoteDataSource.getInviteCode()

return response.toDomain()
}

override suspend fun regenerateInviteCode(): InviteCodeResult {
val response = connectRemoteDataSource.regenerateInviteCode()

return response.toDomain()
}

override suspend fun getVerifyInviteCode(code: String): Boolean {
val response = connectRemoteDataSource.getVerifyInviteCode(code = code)

return response.isVerified
}

override suspend fun connectRequest(
invitationCode: String,
startDate: String,
totalSession: Int,
completedSession: Int,
): ConnectRequestResult {
val response = connectRemoteDataSource.connectRequest(
connectRequest = ConnectRequest(
invitationCode = invitationCode,
startDate = startDate,
totalPtCount = totalSession,
finishedPtCount = completedSession,
),
)
return response.toDomain()
}

override suspend fun getConnectedTraineeInfo(
trainerId: String,
traineeId: String,
): ConnectedResult {
val response = connectRemoteDataSource.getConnectedTraineeInfo(
trainerId = trainerId,
traineeId = traineeId,
)
return response.toDomain()
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package co.kr.data.repository.di

import co.kr.data.repository.ConnectRepositoryImpl
import co.kr.data.repository.LoginRepositoryImpl
import co.kr.data.repository.SignUpRepositoryImpl
import co.kr.tnt.domain.repository.ConnectRepository
import co.kr.tnt.domain.repository.LoginRepository
import co.kr.tnt.domain.repository.SignUpRepository
import dagger.Binds
Expand All @@ -21,4 +23,9 @@ internal abstract class RepositoryModule {
abstract fun bindsSignUpRepository(
repository: SignUpRepositoryImpl,
): SignUpRepository

@Binds
abstract fun bindConnectRepository(
repository: ConnectRepositoryImpl,
): ConnectRepository
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package co.kr.tnt.domain.model

data class ConnectRequestResult(
val trainerName: String,
val traineeName: String,
val trainerImage: String,
val traineeImage: String,
)
Loading

0 comments on commit 1fcce19

Please sign in to comment.