Skip to content

Commit

Permalink
Merge pull request #71 from YAPP-Github/feature/TNT-181
Browse files Browse the repository at this point in the history
[TNT-181] ํŠธ๋ ˆ์ด๋‹ˆ ํ™ˆ ํ™”๋ฉด ์ผ๋ณ„ ๊ธฐ๋ก UI ๊ตฌํ˜„
  • Loading branch information
SeonJeongk authored Feb 9, 2025
2 parents 1f55169 + 0514a9f commit af280d6
Show file tree
Hide file tree
Showing 16 changed files with 675 additions and 90 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ private fun TnTTrainerSessionRecordCardPreview() {
TnTTheme {
TnTSessionRecordCard(
name = "๊น€ํšŒ์›",
tagText = "8ํšŒ์ฐจ ์ˆ˜์—…",
tagText = "8",
startTime = "์˜คํ›„ 17:00",
endTime = "์˜คํ›„ 18:00",
defaultImage = painterResource(R.drawable.img_default),
Expand All @@ -382,7 +382,7 @@ private fun TnTTraineeSessionRecordCardPreview() {
TnTTheme {
TnTSessionRecordCard(
name = "๊น€๋ฏผ์ˆ˜ ํŠธ๋ ˆ์ด๋„ˆ",
tagText = "6ํšŒ์ฐจ ์ˆ˜์—…",
tagText = "6",
startTime = "์˜คํ›„ 17:00",
endTime = "์˜คํ›„ 18:00",
defaultImage = painterResource(R.drawable.img_default),
Expand Down
1 change: 1 addition & 0 deletions core/designsystem/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<string name="received_feedback">๋ฐ›์€ ํ”ผ๋“œ๋ฐฑ</string>
<string name="make_pt_session_record">PT ์ˆ˜์—… ๊ธฐ๋ก ๋‚จ๊ธฐ๊ธฐ</string>
<string name="see_pt_session_record">์ˆ˜์—… ๊ธฐ๋ก ๋ณด๊ธฐ</string>
<string name="lesson_count">%sํšŒ์ฐจ ์ˆ˜์—…</string>

<!-- Calendar -->
<string name="year_month_format">yyyy๋…„ M์›”</string>
Expand Down
14 changes: 11 additions & 3 deletions core/ui/src/main/java/co/kr/tnt/ui/model/RecordChip.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,29 @@ package co.kr.tnt.ui.model
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import co.kr.tnt.core.ui.R
import co.kr.tnt.designsystem.component.chip.model.ChipStyle
import co.kr.tnt.domain.model.RecordType

sealed interface RecordChip {
val title: String
val emoji: String?
val chipStyle: ChipStyle

data class MealChip(
override val title: String,
override val emoji: String,
override val chipStyle: ChipStyle,
) : RecordChip
data class ExerciseChip(
override val title: String,
override val emoji: String? = null,
override val chipStyle: ChipStyle,
) : RecordChip
data class PTSessionChip(
override val title: String,
val sessionCount: Int,
override val emoji: String,
override val chipStyle: ChipStyle,
) : RecordChip

companion object {
Expand All @@ -40,7 +45,7 @@ sealed interface RecordChip {
RecordType.MealType.DINNER -> "๐ŸŒ™"
RecordType.MealType.SNACK -> "๐Ÿฐ"
}
MealChip(title, emoji)
MealChip(title, emoji, ChipStyle.PINK)
}

is RecordType.ExerciseType -> {
Expand All @@ -51,13 +56,16 @@ sealed interface RecordChip {
RecordType.ExerciseType.SHOULDER -> stringResource(R.string.exercise_shoulder)
RecordType.ExerciseType.CARDIO -> stringResource(R.string.exercise_cardio)
}
ExerciseChip(title)
ExerciseChip(
title = title,
chipStyle = ChipStyle.BLUE,
)
}

is RecordType.PTSessionType -> {
val title = stringResource(R.string.pt_session, type.sessionCount)
val emoji = "๐Ÿ’ช"
PTSessionChip(title, type.sessionCount, emoji)
PTSessionChip(title, type.sessionCount, emoji, ChipStyle.BLUE)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package co.kr.data.network.model.trainee

import co.kr.tnt.domain.model.RecordType
import co.kr.tnt.domain.model.RecordType.ExerciseType
import co.kr.tnt.domain.model.RecordType.MealType
import co.kr.tnt.domain.model.trainee.DailyRecord
import co.kr.tnt.domain.model.trainee.PtSession
import co.kr.tnt.domain.model.trainee.TraineeDailyRecord
import co.kr.tnt.domain.utils.DateFormatter
import kotlinx.serialization.Serializable

@Serializable
data class DailyRecordsResponse(
val date: String,
val lessons: PtSessionResponse?,
val records: List<RecordResponse>,
)

@Serializable
data class PtSessionResponse(
val ptSessionId: String,
val trainerName: String,
val trainerImage: String?,
val session: Int,
val startTime: String,
val endTime: String,
val hasRecord: Boolean,
)

@Serializable
data class RecordResponse(
val recordId: String,
val recordType: String,
val recordTime: String,
val recordImage: String?,
val recordContents: String,
val feedbackCount: Int,
)

fun DailyRecordsResponse.toDomain(dateFormatter: DateFormatter) =
TraineeDailyRecord(
date = dateFormatter.parse(date),
ptSession = lessons?.toDomain(dateFormatter),
record = records.map { it.toDomain(dateFormatter) },
)

fun PtSessionResponse.toDomain(dateFormatter: DateFormatter) = PtSession(
ptSessionId = ptSessionId,
trainerName = trainerName,
trainerImage = trainerImage,
session = session,
startTime = dateFormatter.parseDateTime(startTime),
endTime = dateFormatter.parseDateTime(endTime),
hasRecord = hasRecord,
)

fun RecordResponse.toDomain(dateFormatter: DateFormatter) = DailyRecord(
recordId = recordId,
recordType = recordType.toRecordType() ?: MealType.BREAKFAST,
recordTime = dateFormatter.parseDateTime(recordTime),
recordImage = recordImage,
recordContents = recordContents,
feedbackCount = feedbackCount,
)

// TODO : ์ˆ˜์ •
fun String.toRecordType(): RecordType? {
return when (this.uppercase()) {
"BREAKFAST" -> MealType.BREAKFAST
"LUNCH" -> MealType.LUNCH
"DINNER" -> MealType.DINNER
"SNACK" -> MealType.SNACK

"UPPER_BODY" -> ExerciseType.UPPER_BODY
"LOWER_BODY" -> ExerciseType.LOWER_BODY
"BACK" -> ExerciseType.BACK
"SHOULDER" -> ExerciseType.SHOULDER
"CARDIO" -> ExerciseType.CARDIO

else -> null
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package co.kr.data.network.model.trainee

import co.kr.tnt.domain.model.trainee.TraineeDailyRecordStatus
import co.kr.tnt.domain.utils.DateFormatter
import kotlinx.serialization.Serializable

@Serializable
data class MonthlyRecordedDatesResponse(
val calendarRecordInfo: List<RecordedDateResponse>,
)

@Serializable
data class RecordedDateResponse(
val date: String,
)

fun RecordedDateResponse.toDomain(dateFormatter: DateFormatter) =
TraineeDailyRecordStatus(
date = dateFormatter.parse(date),
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
package co.kr.data.repository

import co.kr.data.network.model.trainee.DailyRecordsResponse
import co.kr.data.network.model.trainee.MonthlyRecordedDatesResponse
import co.kr.data.network.model.trainee.PtSessionResponse
import co.kr.data.network.model.trainee.RecordResponse
import co.kr.data.network.model.trainee.RecordedDateResponse
import co.kr.data.network.model.trainee.toDomain
import co.kr.tnt.domain.model.trainee.TraineeDailyRecord
import co.kr.tnt.domain.model.trainee.TraineeDailyRecordStatus
import co.kr.tnt.domain.repository.TraineeRepository
import co.kr.tnt.domain.utils.DateFormatter
import java.time.LocalDate
import java.time.YearMonth
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
internal class TraineeRepositoryImpl @Inject constructor(
private val dateFormatter: DateFormatter,
) : TraineeRepository {
// TODO : API์— ๋งž์ถฐ ์ˆ˜์ •
override suspend fun getDailyDataStatus(yearMonth: YearMonth): List<TraineeDailyRecordStatus> {
val result = MonthlyRecordedDatesResponse(
listOf(
RecordedDateResponse(date = "2025-02-03"),
RecordedDateResponse(date = "2025-02-08"),
RecordedDateResponse(date = "2025-02-10"),
RecordedDateResponse(date = "2025-02-15"),
RecordedDateResponse(date = "2025-02-23"),
),
).calendarRecordInfo.map { response ->
response.toDomain(dateFormatter)
}

return result
}

override suspend fun getTraineeDailyRecord(day: LocalDate): TraineeDailyRecord {
val result = listOf(
DailyRecordsResponse(
date = "2025-02-03",
lessons = PtSessionResponse(
ptSessionId = "CDE35K32",
trainerName = "๊น€ํ—ฌ์Šค",
trainerImage = "https://buly.kr/44x6xFN",
session = 12,
startTime = "2025-02-03T08:00:00.000Z",
endTime = "2025-02-03T09:00:00.000Z",
hasRecord = true,
),
records = listOf(
RecordResponse(
recordId = "VDF1D907",
recordType = "BREAKFAST",
recordTime = "2025-02-03T08:00:00.000Z",
recordImage = "https://buly.kr/BpESNP5",
recordContents = "์•„์นจ์œผ๋กœ ๊ณ„๋ž€ 2๊ฐœ ๋จน์—ˆ์Šต๋‹ˆ๋‹ค.",
feedbackCount = 1,
),
RecordResponse(
recordId = "VDF1D907",
recordType = "LUNCH",
recordTime = "2025-02-03T13:00:00.000Z",
recordImage = "https://buly.kr/BpESNP5",
recordContents = "์ ์‹ฌ์œผ๋กœ ๊ณ„๋ž€ 5๊ฐœ ๋จน์—ˆ์Šต๋‹ˆ๋‹ค.",
feedbackCount = 0,
),
),
),
DailyRecordsResponse(
date = "2025-02-08",
lessons = null,
records = listOf(
RecordResponse(
recordId = "VDF1D907",
recordType = "BREAKFAST",
recordTime = "2025-02-08T13:00:00.000Z",
recordImage = "https://buly.kr/BpESNP5",
recordContents = "๊ณ„๋ž€ 2๊ฐœ ๋จน์—ˆ์Šต๋‹ˆ๋‹ค.",
feedbackCount = 1,
),
RecordResponse(
recordId = "VDF1D907",
recordType = "SNACK",
recordTime = "2025-02-08T15:00:00.000Z",
recordImage = "https://buly.kr/BpESNP5",
recordContents = "๊ณ„๋ž€ ๋ฐ˜๊ฐœ ๋จน์—ˆ์Šต๋‹ˆ๋‹ค.",
feedbackCount = 0,
),
RecordResponse(
recordId = "VDF1D907",
recordType = "DINNER",
recordTime = "2025-02-08T18:40:00.000Z",
recordImage = null,
recordContents = "์ €๋…์œผ๋กœ ์†Œ๊ณ ๊ธฐ ๋จน์—ˆ์Šต๋‹ˆ๋‹ค.",
feedbackCount = 2,
),
),
),
DailyRecordsResponse(
date = "2025-02-15",
lessons = PtSessionResponse(
ptSessionId = "OSI93DG1",
trainerName = "์ด๊ฐ•์‚ฌ",
trainerImage = null,
session = 15,
startTime = "2025-02-15T18:00:00.000Z",
endTime = "2025-02-15T19:00:00.000Z",
hasRecord = true,
),
records = listOf(
RecordResponse(
recordId = "VDF1D907",
recordType = "LUNCH",
recordTime = "2025-02-15T13:00:00.000Z",
recordImage = null,
recordContents = "๋น„๋น”๋ฐฅ, ๋ฐ”๋‚˜๋‚˜ 1๊ฐœ",
feedbackCount = 1,
),
RecordResponse(
recordId = "VDF1D907",
recordType = "DINNER",
recordTime = "2025-02-03T20:00:00.000Z",
recordImage = "https://buly.kr/BpESNP5",
recordContents = "๊ณ„๋ž€ 5๊ฐœ ๋จน์—ˆ์Šต๋‹ˆ๋‹ค.",
feedbackCount = 0,
),
),
),
DailyRecordsResponse(
date = "2025-02-10",
lessons = PtSessionResponse(
ptSessionId = "CDK392DF",
trainerName = "๋ฐ•ํŠธ๋ ˆ์ด๋„ˆ",
trainerImage = null,
session = 10,
startTime = "2025-02-10T14:30:00.000Z",
endTime = "2025-02-10T15:30:00.000Z",
hasRecord = false,
),
records = emptyList(),
),
DailyRecordsResponse(
date = "2025-02-23",
lessons = PtSessionResponse(
ptSessionId = "CDE35K32",
trainerName = "์ •ํŠธ๋ ˆ์ด๋„ˆ",
trainerImage = "https://buly.kr/44x6xFN",
session = 25,
startTime = "2025-02-23T06:00:00.000Z",
endTime = "2025-02-23T06:50:00.000Z",
hasRecord = true,
),
records = emptyList(),
),
).map { response ->
response.toDomain(dateFormatter)
}.firstOrNull { it.date == day }

val noData = TraineeDailyRecord(
date = day,
ptSession = null,
record = emptyList(),
)

return result ?: noData
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ 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.data.repository.TraineeRepositoryImpl
import co.kr.data.repository.TrainerRepositoryImpl
import co.kr.tnt.domain.repository.ConnectRepository
import co.kr.tnt.domain.repository.LoginRepository
import co.kr.tnt.domain.repository.SignUpRepository
import co.kr.tnt.domain.repository.TraineeRepository
import co.kr.tnt.domain.repository.TrainerRepository
import dagger.Binds
import dagger.Module
Expand Down Expand Up @@ -35,4 +37,9 @@ internal abstract class RepositoryModule {
abstract fun bindTrainerRepository(
repository: TrainerRepositoryImpl,
): TrainerRepository

@Binds
abstract fun bindTraineeRepository(
repository: TraineeRepositoryImpl,
): TraineeRepository
}
Loading

0 comments on commit af280d6

Please sign in to comment.