diff --git a/core/ui/src/main/java/com/ssing/core/ui/common/component/SsingMatchingDetailCard.kt b/core/ui/src/main/java/com/ssing/core/ui/common/component/SsingMatchingDetailCard.kt index 9ead3fd93..72fa6c0aa 100644 --- a/core/ui/src/main/java/com/ssing/core/ui/common/component/SsingMatchingDetailCard.kt +++ b/core/ui/src/main/java/com/ssing/core/ui/common/component/SsingMatchingDetailCard.kt @@ -384,7 +384,7 @@ private fun SsingClassDetailCardPreview( nickname = "김OO", teamCount = 0, totalCount = totalCount, - classDateTime = "강사와 만난 후 강습 시작", + classDateTime = "강사와 만난 후 강습 시작돼요", location = "OOO 리조트", duration = "0시간", maxCapacity = 0, diff --git a/data/src/main/java/com/ssing/data/matching/instructormatching/model/InstructorMatchingActive.kt b/data/src/main/java/com/ssing/data/matching/instructormatching/model/InstructorMatchingActive.kt index 78aba9cfc..45b0c904d 100644 --- a/data/src/main/java/com/ssing/data/matching/instructormatching/model/InstructorMatchingActive.kt +++ b/data/src/main/java/com/ssing/data/matching/instructormatching/model/InstructorMatchingActive.kt @@ -13,4 +13,5 @@ data class InstructorMatchingSetting( val availableDurationMinutes: List, val maxHeadcount: Int, val equipmentReady: Boolean, + val estimatedLessonPriceAmount: Int?, ) diff --git a/data/src/main/java/com/ssing/data/matching/instructormatching/remote/dto/response/InstructorMatchingOffersResponse.kt b/data/src/main/java/com/ssing/data/matching/instructormatching/remote/dto/response/InstructorMatchingOffersResponse.kt index 68b645b43..0aba544b5 100644 --- a/data/src/main/java/com/ssing/data/matching/instructormatching/remote/dto/response/InstructorMatchingOffersResponse.kt +++ b/data/src/main/java/com/ssing/data/matching/instructormatching/remote/dto/response/InstructorMatchingOffersResponse.kt @@ -18,6 +18,7 @@ internal data class InstructorMatchingSettingResponse( @SerialName("availableDurationMinutes") val availableDurationMinutes: List, @SerialName("maxHeadcount") val maxHeadcount: Int, @SerialName("equipmentReady") val equipmentReady: Boolean, + @SerialName("estimatedLessonPriceAmount") val estimatedLessonPriceAmount: Int? = null, ) @Serializable diff --git a/data/src/main/java/com/ssing/data/matching/instructormatching/repository/impl/InstructorMatchingRepositoryImpl.kt b/data/src/main/java/com/ssing/data/matching/instructormatching/repository/impl/InstructorMatchingRepositoryImpl.kt index 5932d9f95..743613404 100644 --- a/data/src/main/java/com/ssing/data/matching/instructormatching/repository/impl/InstructorMatchingRepositoryImpl.kt +++ b/data/src/main/java/com/ssing/data/matching/instructormatching/repository/impl/InstructorMatchingRepositoryImpl.kt @@ -187,6 +187,7 @@ internal class InstructorMatchingRepositoryImpl @Inject constructor( availableDurationMinutes = availableDurationMinutes, maxHeadcount = maxHeadcount, equipmentReady = equipmentReady, + estimatedLessonPriceAmount = estimatedLessonPriceAmount, ) private fun InstructorMatchingOfferDecisionResponse.toModel(): InstructorMatchingOfferDecision = diff --git a/presentation/consumer-lesson/src/main/java/com/ssing/presentation/consumerlesson/mapper/LessonInfoToUiModel.kt b/presentation/consumer-lesson/src/main/java/com/ssing/presentation/consumerlesson/mapper/LessonInfoToUiModel.kt index b41b3cd21..9713598f6 100644 --- a/presentation/consumer-lesson/src/main/java/com/ssing/presentation/consumerlesson/mapper/LessonInfoToUiModel.kt +++ b/presentation/consumer-lesson/src/main/java/com/ssing/presentation/consumerlesson/mapper/LessonInfoToUiModel.kt @@ -16,9 +16,10 @@ internal fun ConsumerLessonInfo.toUiModel( tags = persistentListOf(displaySport(basic.sport), displayLessonLevel(basic.lessonLevel)), teamNicknames = matchingRequests .map { it.representativeMemberName } + .ifEmpty { basic.representativeConsumerNames } .toPersistentList(), totalCount = basic.totalHeadcount, place = basic.resort.displayName, duration = formatMinutesText(durationMinutes), price = myTeamLessonPrice, -) \ No newline at end of file +) diff --git a/presentation/consumer-matching/src/main/java/com/ssing/presentation/consumermatching/screen/ConsumerMatchingResultScreen.kt b/presentation/consumer-matching/src/main/java/com/ssing/presentation/consumermatching/screen/ConsumerMatchingResultScreen.kt index dae3d8e45..6f673ce43 100644 --- a/presentation/consumer-matching/src/main/java/com/ssing/presentation/consumermatching/screen/ConsumerMatchingResultScreen.kt +++ b/presentation/consumer-matching/src/main/java/com/ssing/presentation/consumermatching/screen/ConsumerMatchingResultScreen.kt @@ -55,7 +55,7 @@ internal fun ConsumerMatchingResultRoute( SsingModal( onDismissRequest = viewModel::closeCancelModal, title = "매칭을 취소할까요?", - text = "홈으로 이동하면 현재 매칭된 강사와의 연결이 취소됩니다", + text = "홈으로 이동하면 현재 매칭된 강사와의 연결이 취소돼요", primaryText = "계속 보기", onPrimary = viewModel::closeCancelModal, primaryStyle = SsingButtonStyle.GRAY, diff --git a/presentation/consumer-payment/src/main/java/com/ssing/presentation/consumerpayment/PaymentContract.kt b/presentation/consumer-payment/src/main/java/com/ssing/presentation/consumerpayment/PaymentContract.kt index 9e2202543..24ee6615f 100644 --- a/presentation/consumer-payment/src/main/java/com/ssing/presentation/consumerpayment/PaymentContract.kt +++ b/presentation/consumer-payment/src/main/java/com/ssing/presentation/consumerpayment/PaymentContract.kt @@ -13,7 +13,7 @@ internal interface PaymentContract { val showCancelModal: Boolean = false, val nickname: String = "", val tags: ImmutableList = persistentListOf(), - val classDateTime: String = "강사와 만난 뒤 강습 시작", + val classDateTime: String = "강사와 만난 뒤 강습 시작돼요", val location: String = "", val duration: String = "", val participant: String = "", @@ -29,4 +29,4 @@ internal interface PaymentContract { data object NavigateToHome : Effect data class ShowToast(val message: String) : Effect } -} \ No newline at end of file +} diff --git a/presentation/instructor-home/src/main/java/com/ssing/presentation/instructorhome/InstructorHomeViewModel.kt b/presentation/instructor-home/src/main/java/com/ssing/presentation/instructorhome/InstructorHomeViewModel.kt index eef5137f7..95cf6f5cf 100644 --- a/presentation/instructor-home/src/main/java/com/ssing/presentation/instructorhome/InstructorHomeViewModel.kt +++ b/presentation/instructor-home/src/main/java/com/ssing/presentation/instructorhome/InstructorHomeViewModel.kt @@ -130,11 +130,17 @@ internal class InstructorHomeViewModel @Inject constructor( } fun onMatchingClick() { - // 확정/진행 중인 강습이 있으면 즉시매칭 시작을 막는다. if (uiState.value.hasActiveLesson) { sendEffect(InstructorHomeContract.Effect.ShowToast(MSG_ACTIVE_LESSON_BLOCK)) return } + val ongoingOffer = uiState.value.lessonCards + .filterIsInstance() + .firstOrNull { it.status == Status.Matched && it.offerId != null } + if (ongoingOffer != null) { + sendEffect(InstructorHomeContract.Effect.NavigateToMatchingWaiting(offerId = ongoingOffer.offerId)) + return + } sendEffect(InstructorHomeContract.Effect.NavigateToMatching) } diff --git a/presentation/instructor-matching/src/main/java/com/ssing/presentation/instructormatching/MatchingViewModel.kt b/presentation/instructor-matching/src/main/java/com/ssing/presentation/instructormatching/MatchingViewModel.kt index 94a20f219..81e37402d 100644 --- a/presentation/instructor-matching/src/main/java/com/ssing/presentation/instructormatching/MatchingViewModel.kt +++ b/presentation/instructor-matching/src/main/java/com/ssing/presentation/instructormatching/MatchingViewModel.kt @@ -21,6 +21,7 @@ import com.ssing.presentation.instructormatching.model.LessonSummaryUiModel import com.ssing.presentation.instructormatching.model.LevelOption import com.ssing.presentation.instructormatching.model.MatchingExposureUiState import com.ssing.presentation.instructormatching.model.MatchingOfferUiModel +import com.ssing.presentation.instructormatching.model.MatchingWaitingUiState import com.ssing.presentation.instructormatching.model.OfferStatusOption import com.ssing.presentation.instructormatching.model.ParticipantUiModel import com.ssing.presentation.instructormatching.model.SportOption @@ -301,8 +302,12 @@ internal class MatchingViewModel @Inject constructor( instructorMatchingRepository.fetchMatchingActive() .onSuccess { active -> Timber.d("matching-offers 응답: $active") - // 저장된 조건은 항상 복원한다(대기 화면 조건 카드/조건 수정용). - updateState { copy(exposure = exposure.applyMatchingSetting(active.setting)) } + updateState { + copy( + exposure = exposure.applyMatchingSetting(active.setting), + waiting = waiting.applyMatchingSetting(active.setting), + ) + } val activeOfferId = active.offerId offerId = activeOfferId when { @@ -440,6 +445,13 @@ internal class MatchingViewModel @Inject constructor( isNoticeChecked = setting.equipmentReady, ) + private fun MatchingWaitingUiState.applyMatchingSetting( + setting: InstructorMatchingSetting, + ): MatchingWaitingUiState = copy( + price = setting.estimatedLessonPriceAmount ?: price, + equipmentStatus = if (setting.equipmentReady) "착용 완료" else "", + ) + private fun currentOffer(): MatchingOfferUiModel? = when (val phase = uiState.value.phase) { is MatchingPhase.OfferArrived -> phase.offer diff --git a/presentation/instructor-matching/src/main/java/com/ssing/presentation/instructormatching/model/MatchingUiModel.kt b/presentation/instructor-matching/src/main/java/com/ssing/presentation/instructormatching/model/MatchingUiModel.kt index 1035ceaee..057d31110 100644 --- a/presentation/instructor-matching/src/main/java/com/ssing/presentation/instructormatching/model/MatchingUiModel.kt +++ b/presentation/instructor-matching/src/main/java/com/ssing/presentation/instructormatching/model/MatchingUiModel.kt @@ -4,11 +4,6 @@ import androidx.compose.runtime.Immutable import com.ssing.core.ui.common.component.Gender import com.ssing.core.ui.common.component.Participant - -// TODO(매칭-API): API 연동 시 MatchingRepository 내 private 메소드로 DTO → UiModel 변환 구현 -// (sport/lessonLevel enum 문자열 → label, durationMinutes → hours 등) - - /** * 강습 종목 옵션 **/ @@ -88,7 +83,7 @@ internal data class MatchingOfferUiModel( val expiresAtMillis: Long?, val nickname: String = "", val teamCount: Int = 0, - val classDateTime: String = "강습생과 만난 직후 강습 시작", + val classDateTime: String = "강습생과 만난 직후 강습 시작돼요", val participant: String = "", val participants: List = emptyList(), val isPaid: Boolean = false, @@ -117,7 +112,7 @@ internal data class LessonSummaryUiModel( internal data class MatchingWaitingUiState( val nickname: String = "", val teamCount: Int = 0, - val classDateTime: String = "강습생과 만난 직후 강습 시작", + val classDateTime: String = "강습생과 만난 직후 강습 시작돼요", val participant: String = "", val participants: List = emptyList(), val isPaid: Boolean = false, diff --git a/presentation/instructor-matching/src/main/java/com/ssing/presentation/instructormatching/screen/MatchingOfferScreen.kt b/presentation/instructor-matching/src/main/java/com/ssing/presentation/instructormatching/screen/MatchingOfferScreen.kt index 44ae2e6de..4fafc6930 100644 --- a/presentation/instructor-matching/src/main/java/com/ssing/presentation/instructormatching/screen/MatchingOfferScreen.kt +++ b/presentation/instructor-matching/src/main/java/com/ssing/presentation/instructormatching/screen/MatchingOfferScreen.kt @@ -104,7 +104,7 @@ private fun MatchingOfferScreenPreview() { expiresAtMillis = null, nickname = "홍지민", teamCount = 4, - classDateTime = "강습생과 만난 직후 강습 시작", + classDateTime = "강습생과 만난 직후 강습 시작돼요", participants = listOf( ParticipantUiModel(age = 11, isMale = true), ParticipantUiModel(age = 11, isMale = true), diff --git a/presentation/instructor-matching/src/main/java/com/ssing/presentation/instructormatching/screen/MatchingPendingScreen.kt b/presentation/instructor-matching/src/main/java/com/ssing/presentation/instructormatching/screen/MatchingPendingScreen.kt index 407517621..400e1de30 100644 --- a/presentation/instructor-matching/src/main/java/com/ssing/presentation/instructormatching/screen/MatchingPendingScreen.kt +++ b/presentation/instructor-matching/src/main/java/com/ssing/presentation/instructormatching/screen/MatchingPendingScreen.kt @@ -1,10 +1,11 @@ package com.ssing.presentation.instructormatching.screen import androidx.compose.foundation.background -import com.ssing.presentation.instructormatching.R import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.widthIn @@ -25,6 +26,7 @@ import com.ssing.core.ui.common.component.SsingButtonStyle import com.ssing.core.ui.common.component.SsingHeader import com.ssing.core.ui.common.component.SsingTopBar import com.ssing.core.ui.designsystem.theme.SSINGTheme +import com.ssing.presentation.instructormatching.R import com.ssing.presentation.instructormatching.component.MatchingOfferSummaryDetailCard import com.ssing.presentation.instructormatching.model.LessonSummaryUiModel import com.ssing.presentation.instructormatching.model.MatchingOfferUiModel @@ -82,6 +84,7 @@ internal fun MatchingPendingScreen( modifier = Modifier.padding(horizontal = 16.dp), ) } + Spacer(modifier = Modifier.height(16.dp)) SsingButton( text = "대기중", @@ -108,7 +111,7 @@ private fun MatchingPendingScreenPreview() { expiresAtMillis = null, nickname = "홍지민", teamCount = 4, - classDateTime = "강습생과 만난 직후 강습 시작", + classDateTime = "강습생과 만난 직후 강습 시작돼요", participants = listOf( ParticipantUiModel(age = 11, isMale = true), ParticipantUiModel(age = 11, isMale = true), diff --git a/presentation/instructor-matching/src/main/java/com/ssing/presentation/instructormatching/screen/MatchingScreen.kt b/presentation/instructor-matching/src/main/java/com/ssing/presentation/instructormatching/screen/MatchingScreen.kt index f612f5700..f91a34012 100644 --- a/presentation/instructor-matching/src/main/java/com/ssing/presentation/instructormatching/screen/MatchingScreen.kt +++ b/presentation/instructor-matching/src/main/java/com/ssing/presentation/instructormatching/screen/MatchingScreen.kt @@ -172,7 +172,7 @@ private val previewOffer = MatchingOfferUiModel( expiresAtMillis = null, nickname = "홍지민", teamCount = 4, - classDateTime = "강습생과 만난 직후 강습 시작", + classDateTime = "강습생과 만난 직후 강습 시작돼요", participants = listOf( ParticipantUiModel(age = 28, isMale = true), ParticipantUiModel(age = 25, isMale = false), @@ -192,7 +192,7 @@ private val previewOffer = MatchingOfferUiModel( private val previewWaiting = MatchingWaitingUiState( nickname = "홍지민", teamCount = 2, - classDateTime = "강습생과 만난 직후 강습 시작", + classDateTime = "강습생과 만난 직후 강습 시작돼요", participants = listOf( ParticipantUiModel(age = 28, isMale = true), ParticipantUiModel(age = 25, isMale = false), diff --git a/presentation/instructor-matching/src/main/java/com/ssing/presentation/instructormatching/screen/MatchingWaitingScreen.kt b/presentation/instructor-matching/src/main/java/com/ssing/presentation/instructormatching/screen/MatchingWaitingScreen.kt index 7a17fed93..faa493aac 100644 --- a/presentation/instructor-matching/src/main/java/com/ssing/presentation/instructormatching/screen/MatchingWaitingScreen.kt +++ b/presentation/instructor-matching/src/main/java/com/ssing/presentation/instructormatching/screen/MatchingWaitingScreen.kt @@ -33,7 +33,6 @@ import com.ssing.presentation.instructormatching.model.MatchingExposureUiState import com.ssing.presentation.instructormatching.model.MatchingWaitingUiState import com.ssing.presentation.instructormatching.model.ParticipantUiModel import com.ssing.presentation.instructormatching.model.SportOption -import com.ssing.presentation.instructormatching.model.toParticipant import kotlinx.collections.immutable.toPersistentList @Composable @@ -86,7 +85,7 @@ internal fun MatchingWaitingScreen( duration = exposure.selectedDurations.joinToString(" / ") { it.label }, maxCapacity = exposure.maxHeadcount, participant = waiting.participant, - price = waiting.price, + price = waiting.price.takeIf { it > 0 }, equipmentStatus = waiting.equipmentStatus, modifier = Modifier.padding(horizontal = 16.dp, vertical = 12.dp), borderColor = SSINGTheme.colors.borderAlternative, @@ -131,7 +130,7 @@ private fun MatchingWaitingScreenPreview() { waiting = MatchingWaitingUiState( nickname = "김OO", teamCount = 2, - classDateTime = "강습생과 만난 후 강습 시작", + classDateTime = "강습생과 만난 후 강습 시작돼요", participants = listOf( ParticipantUiModel(age = 28, isMale = true), ParticipantUiModel(age = 25, isMale = false),