Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ private fun SsingClassDetailCardPreview(
nickname = "김OO",
teamCount = 0,
totalCount = totalCount,
classDateTime = "강사와 만난 후 강습 시작",
classDateTime = "강사와 만난 후 강습 시작돼요",
location = "OOO 리조트",
duration = "0시간",
maxCapacity = 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ data class InstructorMatchingSetting(
val availableDurationMinutes: List<Int>,
val maxHeadcount: Int,
val equipmentReady: Boolean,
val estimatedLessonPriceAmount: Int?,
)
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ internal data class InstructorMatchingSettingResponse(
@SerialName("availableDurationMinutes") val availableDurationMinutes: List<Int>,
@SerialName("maxHeadcount") val maxHeadcount: Int,
@SerialName("equipmentReady") val equipmentReady: Boolean,
@SerialName("estimatedLessonPriceAmount") val estimatedLessonPriceAmount: Int? = null,
)

@Serializable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ internal class InstructorMatchingRepositoryImpl @Inject constructor(
availableDurationMinutes = availableDurationMinutes,
maxHeadcount = maxHeadcount,
equipmentReady = equipmentReady,
estimatedLessonPriceAmount = estimatedLessonPriceAmount,
)

private fun InstructorMatchingOfferDecisionResponse.toModel(): InstructorMatchingOfferDecision =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
)
)
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ internal fun ConsumerMatchingResultRoute(
SsingModal(
onDismissRequest = viewModel::closeCancelModal,
title = "매칭을 취소할까요?",
text = "홈으로 이동하면 현재 매칭된 강사와의 연결이 취소됩니다",
text = "홈으로 이동하면 현재 매칭된 강사와의 연결이 취소돼요",
primaryText = "계속 보기",
onPrimary = viewModel::closeCancelModal,
primaryStyle = SsingButtonStyle.GRAY,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ internal interface PaymentContract {
val showCancelModal: Boolean = false,
val nickname: String = "",
val tags: ImmutableList<String> = persistentListOf(),
val classDateTime: String = "강사와 만난 뒤 강습 시작",
val classDateTime: String = "강사와 만난 뒤 강습 시작돼요",
val location: String = "",
val duration: String = "",
val participant: String = "",
Expand All @@ -29,4 +29,4 @@ internal interface PaymentContract {
data object NavigateToHome : Effect
data class ShowToast(val message: String) : Effect
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<Reservation>()
.firstOrNull { it.status == Status.Matched && it.offerId != null }
if (ongoingOffer != null) {
sendEffect(InstructorHomeContract.Effect.NavigateToMatchingWaiting(offerId = ongoingOffer.offerId))
return
}
sendEffect(InstructorHomeContract.Effect.NavigateToMatching)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 등)


/**
* 강습 종목 옵션
**/
Expand Down Expand Up @@ -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<ParticipantUiModel> = emptyList(),
val isPaid: Boolean = false,
Expand Down Expand Up @@ -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<ParticipantUiModel> = emptyList(),
val isPaid: Boolean = false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand Down Expand Up @@ -82,6 +84,7 @@ internal fun MatchingPendingScreen(
modifier = Modifier.padding(horizontal = 16.dp),
)
}
Spacer(modifier = Modifier.height(16.dp))

SsingButton(
text = "대기중",
Expand All @@ -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),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -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),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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),
Expand Down
Loading