Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
0105bce
mod/#114: 자녀 회원가입 및 온보딩 문구 수정
seungjae708 Mar 18, 2026
7015bfe
mod/#114: 자녀 여정뷰 가기 전, 2초간 대기(로딩창)
seungjae708 Mar 18, 2026
4ef9e22
mod/#114: KidMapScreen 상단 패딩 추가
seungjae708 Mar 18, 2026
9382290
mod/#114: 시간 포맷 수정 (hh:mm -> hh : mm)
seungjae708 Mar 18, 2026
4e03272
mod/#114: KidMapItemUiModel 매핑 로직 수정 및 ViewModel 내 상태 처리 로직 분리
seungjae708 Mar 18, 2026
642f6f1
mod/#114: KidMapItemUiModel 매핑 로직 수정 및 ViewModel 내 상태 처리 로직 분리
seungjae708 Mar 18, 2026
8af0373
Merge remote-tracking branch 'origin/mod-#114-journey-sprint-qa' into…
seungjae708 Mar 18, 2026
0089378
mod/#114: 아이 미션 및 소원 화면 빈 뷰 추가
seungjae708 Mar 18, 2026
60bbfc1
mod/#114: 다이얼로그 딤드 클릭시 화면 닫힘
seungjae708 Mar 18, 2026
b08c0fc
mod/#114: 아이 회원가입 스낵바 하단 패딩 설정
seungjae708 Mar 18, 2026
b2084de
mod/#114: KieroSnackbar 패딩 수정 및 fillMaxWidth 제거
seungjae708 Mar 18, 2026
9c97bc5
mod/#114: isFireLitToday 필드 추가 및 진행 중인 일정 표시 로직 수정
seungjae708 Mar 22, 2026
c6f2ef8
feat/#114: SSE 쿠폰 이벤트 처리 로직 구현 및 ViewModel 연동
seungjae708 Mar 22, 2026
20f6ad9
mod/#114: KidMissionViewModel 위치 변경 및 import 수정
seungjae708 Mar 22, 2026
cb87814
mod/#114: KidMissionItem 클릭 리스너 제거
seungjae708 Mar 22, 2026
8f5b58c
mod/#114: KID 역할의 토큰 재발급 메서드를 reissueAccessToken으로 수정
seungjae708 Mar 22, 2026
dc8e2bf
mod/#114: API 엔드포인트 수정 및 성공 시 데이터 갱신 로직 추가
seungjae708 Mar 22, 2026
222329a
mod/#114: 불필요한 Companion 및 Forest 참조 제거
seungjae708 Mar 23, 2026
066be08
mod/#114: 불필요한 Forest 참조 제거 및 미사용 매개변수 제거
seungjae708 Mar 23, 2026
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 @@ -18,7 +18,7 @@ private val DATE_FORMAT_WITH_DAY = DateTimeFormatter.ofPattern("yyyy.M.d.(E)", L
private val SERVER_DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm")
private val ALARM_DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy.MM.dd")
private val ALARM_TIME_FORMAT = DateTimeFormatter.ofPattern("HH : mm")
private val KOREAN_TIME_FORMATTER = DateTimeFormatter.ofPattern("a hh:mm", Locale.KOREAN)
private val KOREAN_TIME_FORMATTER = DateTimeFormatter.ofPattern("a hh : mm", Locale.KOREAN)

fun String.formattedDeadLine(): String {
if (this.isBlank()) return ""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,12 @@ import com.kiero.core.designsystem.theme.KieroTheme
fun KieroSnackbar(
message: String,
modifier: Modifier = Modifier,
contentPadding: Dp = 16.dp,
) {
Box(
modifier = modifier
.fillMaxWidth()
.clip(RoundedCornerShape(999.dp))
.background(KieroTheme.colors.gray800)
.padding(contentPadding),
.padding(horizontal = 16.dp, vertical = 10.dp),
contentAlignment = Alignment.Center
) {
Text(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,14 @@ fun KieroDialog(
modifier = modifier
.fillMaxSize()
.background(color = KieroTheme.colors.black.copy(alpha = 0.75f))
.noRippleClickable(onClick = onDismiss)
.padding(horizontal = 16.dp),
contentAlignment = Alignment.Center
) {
Column(
modifier = Modifier
.fillMaxWidth()
.noRippleClickable(onClick = {})
.background(
color = KieroTheme.colors.gray900,
shape = RoundedCornerShape(16.dp)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class TokenRefreshServiceImpl @Inject constructor(
override suspend fun refresh(refreshToken: String, role: UserRole): Result<Pair<AccessToken, RefreshToken>> = suspendRunCatching {
val response = when (role) {
UserRole.PARENT -> reissueService.reissueAccessToken("refreshToken=$refreshToken")
UserRole.KID -> reissueService.reissueToken("refreshToken=$refreshToken")
UserRole.KID -> reissueService.reissueAccessToken("refreshToken=$refreshToken")
}

if (!response.isSuccessful) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.kiero.data.kid.schedule.remote.dto.response.ScheduleProgressResponseD

data class ScheduleProgressModel(
val scheduleCount: Int,
val isFireLitToday: Boolean,
val schedules: List<ScheduleProgressItemModel>
)

Expand All @@ -19,6 +20,7 @@ data class ScheduleProgressItemModel(

fun ScheduleProgressResponseDto.toModel() = ScheduleProgressModel(
scheduleCount = this.scheduleCount,
isFireLitToday = this.isFireLitToday,
schedules = this.schedules.map { it.toModel() }
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import kotlinx.serialization.Serializable
data class ScheduleProgressResponseDto(
@SerialName("scheduleCount")
val scheduleCount: Int,
@SerialName("isFireLitToday")
val isFireLitToday: Boolean,
@SerialName("schedules")
val schedules: List<ScheduleProgressItemDto>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ package com.kiero.data.kid.wish.remote.api
import com.kiero.core.network.model.BaseResponse
import com.kiero.data.kid.wish.remote.dto.response.WishResponseDto
import retrofit2.http.GET
import retrofit2.http.PATCH
import retrofit2.http.POST
import retrofit2.http.Path

interface WishService {
@GET("api/v1/coupons")
suspend fun getCoupons() : BaseResponse<List<WishResponseDto>>

@PATCH("api/v1/coupons/{couponId}")
@POST("api/v1/coupons/{couponId}/purchase")
suspend fun patchCoupon(
@Path("couponId") couponId: Long,
) : BaseResponse<WishResponseDto>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ interface MissionService {
@Query("childId") childId: Long? = null,
): BaseResponse<MissionByDateResponseDto>

@PATCH("api/v1/missions/{missionId}")
@PATCH("api/v1/missions/{missionId}/complete")
suspend fun completeMission(
@Path("missionId") missionId: Long
): BaseResponse<MissionCompleteResponseDto>
Expand Down
7 changes: 7 additions & 0 deletions app/src/main/java/com/kiero/data/sse/manager/SseManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ class SseManager @Inject constructor(
)
val childScheduleEvents: SharedFlow<SseEvent.Kid.Schedule> = _childScheduleEvents.asSharedFlow()

private val _childCouponEvents = MutableSharedFlow<SseEvent.Kid.Coupon>(
replay = 0,
extraBufferCapacity = 1
)
val childCouponEvents: SharedFlow<SseEvent.Kid.Coupon> = _childCouponEvents.asSharedFlow()

private val _childDateEvents = MutableSharedFlow<SseEvent.Kid.Date>(
replay = 0,
extraBufferCapacity = 1
Expand Down Expand Up @@ -216,6 +222,7 @@ class SseManager @Inject constructor(
is SseEvent.Connected -> Timber.d("아이 SSE Connected")
is SseEvent.Kid.Mission -> _childMissionEvents.emit(event)
is SseEvent.Kid.Schedule -> _childScheduleEvents.emit(event)
is SseEvent.Kid.Coupon -> _childCouponEvents.emit(event)
is SseEvent.Kid.Date -> _childDateEvents.emit(event)
else -> Timber.w("자녀 모드에서 알 수 없는 이벤트: $event")
}
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/com/kiero/data/sse/model/SseEvent.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.kiero.data.sse.model

import com.kiero.data.sse.remote.dto.response.CouponDataDto
import com.kiero.data.sse.remote.dto.response.DateDataDto
import com.kiero.data.sse.remote.dto.response.FeedDataDto
import com.kiero.data.sse.remote.dto.response.InviteDataDto
Expand All @@ -21,6 +22,7 @@ sealed interface SseEvent {
sealed interface Kid : SseEvent {
data class Mission(val data: MissionDataDto) : Kid
data class Schedule(val data: ScheduleDataDto) : Kid
data class Coupon(val data: CouponDataDto) : Kid
data class Date(val data: DateDataDto) : Kid
}
}
1 change: 1 addition & 0 deletions app/src/main/java/com/kiero/data/sse/model/SseEventType.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ enum class SseEventType(val value: String) {
FEED("feed"),
MISSION("mission"),
SCHEDULE("schedule"),
COUPON("coupon"),
DATE("date"),
UNKNOWN("unknown");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,19 @@ data class ScheduleDataDto(
val childId: Long? = null
)

// Coupon 이벤트 (COUPON_CREATED)
@Serializable
data class CouponDataDto(
@SerialName("eventType")
val eventType: String, // "COUPON_CREATED"

@SerialName("couponName")
val couponName: String,

@SerialName("price")
val price: Int
)

// Date 이벤트 (DATE_CHANGED)
@Serializable
data class DateDataDto(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.kiero.data.sse.model.RawSseEvent
import com.kiero.data.sse.model.SseEvent
import com.kiero.data.sse.model.SseEventType
import com.kiero.data.sse.remote.datasource.SseDataSource
import com.kiero.data.sse.remote.dto.response.CouponDataDto
import com.kiero.data.sse.remote.dto.response.DateDataDto
import com.kiero.data.sse.remote.dto.response.FeedDataDto
import com.kiero.data.sse.remote.dto.response.InviteDataDto
Expand Down Expand Up @@ -115,6 +116,17 @@ class SseRepositoryImpl @Inject constructor(
}
}

SseEventType.COUPON -> {
try {
val data = json.decodeFromString<CouponDataDto>(raw.data)
Timber.d("🎟️ Coupon 이벤트 파싱 성공: ${data.couponName}")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이모티콘 귀엽네요~

SseEvent.Kid.Coupon(data)
} catch (e: Exception) {
Timber.e(e, "Coupon 파싱 실패: ${raw.data}")
null
}
}

SseEventType.DATE -> {
try {
val data = json.decodeFromString<DateDataDto>(raw.data)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@ fun AuthKidSignupRoute(
when (sideEffect) {
is KidSignupSideEffect.ShowSnackbar -> {
eventTrigger.showSnackbar(
SnackbarState(message = sideEffect.message)
SnackbarState(
message = sideEffect.message,
bottomPadding = 130
)
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class KidSignupViewModel @Inject constructor(
currentState.lastName.text.isBlank() ||
currentState.inviteCode.text.isBlank()) {

_sideEffect.emit(KidSignupSideEffect.ShowSnackbar("이름이나 초대 코드를 다시 확인해줘."))
_sideEffect.emit(KidSignupSideEffect.ShowSnackbar("이름이나 초대코드를 다시 확인해줘!"))
return@launch
}

Expand All @@ -63,7 +63,7 @@ class KidSignupViewModel @Inject constructor(

_sideEffect.emit(KidSignupSideEffect.NavigateToKidOnboarding)
}.onFailure {
_sideEffect.emit(KidSignupSideEffect.ShowSnackbar("이름이나 초대코드를 다시 확인해줘"))
_sideEffect.emit(KidSignupSideEffect.ShowSnackbar("이름이나 초대코드를 다시 확인해줘!"))
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ fun KidInputField(
Row(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 6.dp)
.alpha(if (isError) 1f else 0f),
verticalAlignment = Alignment.CenterVertically
) {
Expand All @@ -88,7 +87,7 @@ fun KidInputField(
Spacer(modifier = Modifier.width(4.dp))

Text(
text = "특수문자나 이모지를 포함하지 않은 이름을 입력해주세요",
text = "특수문자나 이모지를 포함하지 않은 이름을 입력해줘!",
style = KieroTheme.typography.regular.body5,
color = KieroTheme.colors.point,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ private fun KidMapScreen(
)

Column(
modifier = Modifier.fillMaxSize(),
modifier = Modifier
.fillMaxSize()
.padding(top = paddingValues.calculateTopPadding()),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Spacer(modifier = Modifier.height(30.dp))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.kiero.core.designsystem.component.divider.KieroDashedHorizontalDivider
Expand All @@ -35,6 +36,11 @@ fun KidMapListItem(
else -> KieroTheme.colors.gray500.copy(alpha = 0.5f)
}

val dividerColor = when {
item.isOngoing || item.isNext || item.status == KidMapScheduleStatus.PENDING -> KieroTheme.colors.gray600
else -> Color.Transparent
}

Row(
modifier = modifier
.fillMaxWidth()
Expand Down Expand Up @@ -74,7 +80,8 @@ fun KidMapListItem(
}

KieroDashedHorizontalDivider(
color = KieroTheme.colors.gray600,
color = dividerColor,
endColor = dividerColor,
thickness = 1.dp,
modifier = Modifier
.weight(0.25f)
Expand All @@ -100,8 +107,8 @@ private fun KidMapListItemPreview() {
KidMapListItem(
item = KidMapItemUiModel(
name = "꾸비 성수팝업 가기",
startTime = "오후 04:00",
endTime = "오후 05:00",
startTime = "오후 04 : 00",
endTime = "오후 05 : 00",
isOngoing = false,
stoneType = KidJourneyStoneType.COURAGE,
status = KidMapScheduleStatus.COMPLETED
Expand All @@ -111,8 +118,8 @@ private fun KidMapListItemPreview() {
KidMapListItem(
item = KidMapItemUiModel(
name = "꾸비 성수팝업 가기",
startTime = "오후 04:00",
endTime = "오후 05:00",
startTime = "오후 04 : 00",
endTime = "오후 05 : 00",
isOngoing = false,
stoneType = KidJourneyStoneType.COURAGE,
status = KidMapScheduleStatus.FAILED
Expand All @@ -122,19 +129,42 @@ private fun KidMapListItemPreview() {
KidMapListItem(
item = KidMapItemUiModel(
name = "꾸비 성수팝업 가기",
startTime = "오후 04:00",
endTime = "오후 05:00",
startTime = "오후 04 : 00",
endTime = "오후 05 : 00",
isOngoing = true,
stoneType = KidJourneyStoneType.GRIT,
status = KidMapScheduleStatus.PENDING
)
)
// 미래 PENDING 중 첫번째 - 라인 있음, main 색상
KidMapListItem(
item = KidMapItemUiModel(
name = "꾸비 성수팝업 가기",
startTime = "오후 04 : 00",
endTime = "오후 05 : 00",
isOngoing = false,
isNext = true,
stoneType = KidJourneyStoneType.WISDOM,
status = KidMapScheduleStatus.PENDING
)
)
// 미래 PENDING - 라인 있음, white 색상
KidMapListItem(
item = KidMapItemUiModel(
name = "꾸비 성수팝업 가기",
startTime = "오후 04:00",
endTime = "오후 05:00",
startTime = "오후 04 : 00",
endTime = "오후 05 : 00",
isOngoing = false,
isNext = true,
stoneType = KidJourneyStoneType.WISDOM,
status = KidMapScheduleStatus.PENDING
)
)
KidMapListItem(
item = KidMapItemUiModel(
name = "꾸비 성수팝업 가기",
startTime = "오후 04 : 00",
endTime = "오후 05 : 00",
isOngoing = false,
stoneType = KidJourneyStoneType.WISDOM,
status = KidMapScheduleStatus.PENDING
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,33 @@ data class KidMapItemUiModel(
val status: KidMapScheduleStatus = KidMapScheduleStatus.PENDING
)

fun ScheduleProgressItemModel.toUiModel() = KidMapItemUiModel(
name = this.name,
startTime = this.startTime.toKoreanTimeString(),
endTime = this.endTime.toKoreanTimeString(),
isOngoing = this.isOngoing,
stoneType = KidJourneyStoneType.from(this.stoneType),
status = KidMapScheduleStatus.from(this.status)
)
fun ScheduleProgressItemModel.toUiModel(isFireLitToday: Boolean): KidMapItemUiModel {
val mappedStatus = KidMapScheduleStatus.from(this.status)

val validIsOngoing = this.isOngoing && !isFireLitToday &&
(mappedStatus == KidMapScheduleStatus.PENDING || mappedStatus == KidMapScheduleStatus.VERIFIED)

return KidMapItemUiModel(
name = this.name,
startTime = this.startTime.toKoreanTimeString(),
endTime = this.endTime.toKoreanTimeString(),
isOngoing = validIsOngoing,
stoneType = KidJourneyStoneType.from(this.stoneType),
status = mappedStatus
)
}

fun List<ScheduleProgressItemModel>.toUiModelList(isFireLitToday: Boolean): List<KidMapItemUiModel> {
val mappedList = this.map { it.toUiModel(isFireLitToday) }.toMutableList()

val hasOngoing = mappedList.any { it.isOngoing }

if (!hasOngoing) {
val pendingIndex = mappedList.indexOfFirst { it.status == KidMapScheduleStatus.PENDING }
if (pendingIndex != -1) {
mappedList[pendingIndex] = mappedList[pendingIndex].copy(isNext = true)
}
}

return mappedList
}
Loading