Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TNT-179] 트레이너 일별 수업 조회 기능 구현 #69

Merged
merged 4 commits into from
Feb 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -256,9 +256,9 @@ fun TnTSessionRecordCard(
modifier = Modifier
.fillMaxWidth()
.clip(RoundedCornerShape(8.dp))
.clickable(onClick = onClick)
.background(TnTTheme.colors.neutralColors.Neutral100)
.padding(vertical = 12.dp)
.clickable(onClick = onClick),
.padding(vertical = 12.dp),
) {
Image(
painter = painterResource(R.drawable.ic_edit_gray),
Expand Down
16 changes: 16 additions & 0 deletions core/designsystem/src/main/res/drawable/ic_fill_check_false.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="32dp"
android:viewportWidth="32"
android:viewportHeight="32">
<path
android:pathData="M8,0L24,0A8,8 0,0 1,32 8L32,24A8,8 0,0 1,24 32L8,32A8,8 0,0 1,0 24L0,8A8,8 0,0 1,8 0z"
android:fillColor="#E5E5E5"/>
<path
android:pathData="M10.5,16.25L14,19.75L21.5,12.25"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#FAFAFA"
android:strokeLineCap="round"/>
</vector>
16 changes: 16 additions & 0 deletions core/designsystem/src/main/res/drawable/ic_fill_check_true.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="32dp"
android:viewportWidth="32"
android:viewportHeight="32">
<path
android:pathData="M8,0L24,0A8,8 0,0 1,32 8L32,24A8,8 0,0 1,24 32L8,32A8,8 0,0 1,0 24L0,8A8,8 0,0 1,8 0z"
android:fillColor="#FECACA"/>
<path
android:pathData="M10.5,16.25L14,19.75L21.5,12.25"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#FF5D58"
android:strokeLineCap="round"/>
</vector>
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package co.kr.data.network.model.trainer

import co.kr.tnt.domain.model.PtSession
import co.kr.tnt.domain.model.trainer.TrainerDailyPtSession
import co.kr.tnt.domain.utils.DateFormatter
import kotlinx.serialization.Serializable

@Serializable
data class DailyPtSessionsResponse(
val count: Int,
val date: String,
val lessons: List<PtSessionResponse>,
)

@Serializable
data class PtSessionResponse(
val ptLessonId: String,
val traineeId: String,
val traineeName: String,
val traineeProfileImageUrl: String,
val session: Int,
val startTime: String,
val endTime: String,
val isCompleted: Boolean,
)

fun DailyPtSessionsResponse.toDomain(dateFormatter: DateFormatter): TrainerDailyPtSession = TrainerDailyPtSession(
date = dateFormatter.parse(date),
sessions = lessons.map { it.toDomain(dateFormatter) },
)

fun PtSessionResponse.toDomain(dateFormatter: DateFormatter): PtSession = PtSession(
id = ptLessonId,
round = session,
traineeId = traineeId,
traineeName = traineeName,
traineeProfileUrl = traineeProfileImageUrl,
startTime = dateFormatter.parseDateTime(startTime),
endTime = dateFormatter.parseDateTime(endTime),
isCompleted = isCompleted,
)
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package co.kr.data.network.model.trainer

import co.kr.tnt.domain.model.trainer.DailyPtSessionCount
import co.kr.tnt.domain.model.trainer.TrainerDailyPtSessionCount
import co.kr.tnt.domain.utils.DateFormatter
import kotlinx.serialization.Serializable

Expand All @@ -16,7 +16,7 @@ data class PtSessionCountsResponse(
)

fun PtSessionCountsResponse.toDomain(dateFormatter: DateFormatter) =
DailyPtSessionCount(
TrainerDailyPtSessionCount(
date = dateFormatter.parse(date),
count = count,
)
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ 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.model.trainer.DailyPtSessionsResponse
import co.kr.data.network.model.trainer.MonthlyPtSessionCountsResponse
import co.kr.data.network.util.WithoutSessionCheckPath.CHECK_SESSION_PATH
import okhttp3.MultipartBody
Expand Down Expand Up @@ -68,4 +69,9 @@ interface ApiService {
@Query("year") year: Int,
@Query("month") month: Int,
): MonthlyPtSessionCountsResponse

@GET("/trainers/lessons/{date}")
suspend fun getDailyPtSessions(
@Path("date") date: String,
): DailyPtSessionsResponse
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package co.kr.data.network.source

import co.kr.data.network.model.trainer.DailyPtSessionsResponse
import co.kr.data.network.model.trainer.MonthlyPtSessionCountsResponse
import co.kr.data.network.service.ApiService
import co.kr.data.network.util.networkHandler
Expand All @@ -19,4 +20,10 @@ class TrainerRemoteDataSource @Inject constructor(
month = month,
)
}

suspend fun getDailyPtSessions(
date: String,
): DailyPtSessionsResponse = networkHandler {
apiService.getDailyPtSessions(date)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package co.kr.data.repository

import co.kr.data.network.model.trainer.toDomain
import co.kr.data.network.source.TrainerRemoteDataSource
import co.kr.tnt.domain.model.trainer.DailyPtSessionCount
import co.kr.tnt.domain.model.trainer.TrainerDailyPtSession
import co.kr.tnt.domain.model.trainer.TrainerDailyPtSessionCount
import co.kr.tnt.domain.repository.TrainerRepository
import co.kr.tnt.domain.utils.DateFormatter
import java.time.LocalDate
import java.time.YearMonth
import javax.inject.Inject
import javax.inject.Singleton
Expand All @@ -14,11 +16,16 @@ internal class TrainerRepositoryImpl @Inject constructor(
private val trainerRemoteDataSource: TrainerRemoteDataSource,
private val dateFormatter: DateFormatter,
) : TrainerRepository {
override suspend fun getMonthlyPtSessionCounts(yearMonth: YearMonth): List<DailyPtSessionCount> =
override suspend fun getMonthlyPtSessionCounts(yearMonth: YearMonth): List<TrainerDailyPtSessionCount> =
trainerRemoteDataSource.getMonthlyPtSessionCounts(
year = yearMonth.year,
month = yearMonth.monthValue,
).calendarPtLessonCounts.map { response ->
response.toDomain(dateFormatter)
}

override suspend fun getDailyPtSessions(day: LocalDate): TrainerDailyPtSession =
trainerRemoteDataSource.getDailyPtSessions(
date = dateFormatter.format(day, "yyyy-MM-dd"),
).toDomain(dateFormatter)
}
14 changes: 14 additions & 0 deletions domain/src/main/java/co/kr/tnt/domain/model/PtSession.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package co.kr.tnt.domain.model

import java.time.LocalDateTime

data class PtSession(
val id: String,
val round: Int,
val traineeId: String,
val traineeName: String,
val traineeProfileUrl: String,
val startTime: LocalDateTime,
val endTime: LocalDateTime,
val isCompleted: Boolean,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package co.kr.tnt.domain.model.trainer

import co.kr.tnt.domain.model.PtSession
import java.time.LocalDate

data class TrainerDailyPtSession(
val date: LocalDate,
val sessions: List<PtSession>,
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package co.kr.tnt.domain.model.trainer

import java.time.LocalDate

data class DailyPtSessionCount(
data class TrainerDailyPtSessionCount(
val date: LocalDate,
val count: Int,
)
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package co.kr.tnt.domain.repository

import co.kr.tnt.domain.model.trainer.DailyPtSessionCount
import co.kr.tnt.domain.model.trainer.TrainerDailyPtSession
import co.kr.tnt.domain.model.trainer.TrainerDailyPtSessionCount
import java.time.LocalDate
import java.time.YearMonth

interface TrainerRepository {
suspend fun getMonthlyPtSessionCounts(yearMonth: YearMonth): List<DailyPtSessionCount>
suspend fun getMonthlyPtSessionCounts(yearMonth: YearMonth): List<TrainerDailyPtSessionCount>

suspend fun getDailyPtSessions(day: LocalDate): TrainerDailyPtSession
}
27 changes: 23 additions & 4 deletions domain/src/main/java/co/kr/tnt/domain/utils/DateFormatter.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package co.kr.tnt.domain.utils

import java.time.LocalDate
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import javax.inject.Inject
import javax.inject.Singleton
Expand All @@ -9,19 +10,37 @@ import javax.inject.Singleton
class DateFormatter @Inject constructor() {
fun parse(
rawDate: String,
formatter: DateTimeFormatter = DEFAULT_DATE_FORMAT,
formatter: DateTimeFormatter = DEFAULT_DATE_FORMATTER,
): LocalDate {
require(rawDate.isNotBlank())

return LocalDate.parse(rawDate, formatter)
}

fun parseDateTime(
rawDate: String,
formatter: DateTimeFormatter = DEFAULT_DATE_TIME_FORMATTER,
): LocalDateTime {
require(rawDate.isNotBlank())
return LocalDateTime.parse(rawDate, formatter)
}

fun format(
date: LocalDate,
formatter: DateTimeFormatter = DEFAULT_DATE_FORMAT,
formatter: DateTimeFormatter = DEFAULT_DATE_FORMATTER,
): String = formatter.format(date)

fun format(
date: LocalDate,
pattern: String = "yyyy-MM-dd",
): String = DateTimeFormatter.ofPattern(pattern).format(date)

fun format(
date: LocalDateTime,
pattern: String = "yyyy-MM-ddTHH:mm:ss",
): String = DateTimeFormatter.ofPattern(pattern).format(date)

companion object {
private val DEFAULT_DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd")
private val DEFAULT_DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd")
private val DEFAULT_DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package co.kr.tnt.trainer.home

import co.kr.tnt.domain.model.PtSession
import co.kr.tnt.ui.base.UiEvent
import co.kr.tnt.ui.base.UiSideEffect
import co.kr.tnt.ui.base.UiState
Expand All @@ -10,6 +11,7 @@ internal class TrainerHomeContract {
data class TrainerHomeUiState(
val selectedDay: LocalDate = LocalDate.now(),
val dailyPtSessionCount: Map<LocalDate, Int> = mapOf(),
val selectedDayPtSessions: List<PtSession>? = null,
) : UiState

sealed interface TrainerHomeUiEvent : UiEvent {
Expand Down
Loading